// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.cluster;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.api.InternalIdentity;

@Entity
@Table(name="mshost")
public class ManagementServerHostVO implements ManagementServerHost {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id")
	private long id;

	@Column(name="msid", updatable=true, nullable=false)
	private long msid;
	
	@Column(name="runid", updatable=true, nullable=false)
	private long runid;

	@Column(name="name", updatable=true, nullable=true)
	private String name;
	
    @Column(name="state", updatable = true, nullable=false)
    @Enumerated(value=EnumType.STRING)
	private ManagementServerHost.State state;
	
	@Column(name="version", updatable=true, nullable=true)
	private String version;
	
	@Column(name="service_ip", updatable=true, nullable=false)
	private String serviceIP;
	
	@Column(name="service_port", updatable=true, nullable=false)
	private int servicePort;
	
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="last_update", updatable=true, nullable=true)
    private Date lastUpdateTime;
    
    @Column(name=GenericDao.REMOVED_COLUMN)
    private Date removed;
    
	@Column(name="alert_count", updatable=true, nullable=false)
	private int alertCount;

    public ManagementServerHostVO() {
    }
    
    public ManagementServerHostVO(long msid, long runid, String serviceIP, int servicePort, Date updateTime) {
    	this.msid = msid;
    	this.runid = runid;
    	this.serviceIP = serviceIP;
    	this.servicePort = servicePort;
    	this.lastUpdateTime = updateTime;
    }
    
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}
	
	public long getRunid() {
		return runid;
	}
	
	public void setRunid(long runid) {
		this.runid = runid;
	}

	@Override
	public long getMsid() {
		return msid;
	}

	public void setMsid(long msid) {
		this.msid = msid;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public ManagementServerHost.State getState() {
		return this.state;
	}
	
	public void setState(ManagementServerHost.State state) {
		this.state = state;
	}
	
	@Override
	public String getVersion() {
		return version;
	}
	
	public void setVersion(String version) {
		this.version = version;
	}
	
	public String getServiceIP() {
		return serviceIP;
	}

	public void setServiceIP(String serviceIP) {
		this.serviceIP = serviceIP;
	}

	public int getServicePort() {
		return servicePort;
	}

	public void setServicePort(int servicePort) {
		this.servicePort = servicePort;
	}

	public Date getLastUpdateTime() {
		return lastUpdateTime;
	}

	public void setLastUpdateTime(Date lastUpdateTime) {
		this.lastUpdateTime = lastUpdateTime;
	}
	
	public Date getRemoved() {
		return removed;
	}
	
	public void setRemoved(Date removedTime) {
		removed = removedTime;
	}
	
	public int getAlertCount() {
		return alertCount; 
	}
	
	public void setAlertCount(int count) {
		alertCount = count;
	}
	
	@Override
    public String toString() {
        return new StringBuilder("ManagementServer[").append("-").append(id).append("-").append(msid).append("-").append(state).append("]").toString();
    }
}
