// 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.dc;

import java.util.Date;
import java.util.UUID;

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 org.apache.cloudstack.api.Identity;
import com.cloud.org.Grouping;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.api.InternalIdentity;

@Entity
@Table(name = "host_pod_ref")
public class HostPodVO implements Pod {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	long id;

	@Column(name = "name")
	private String name = null;

	@Column(name = "data_center_id")
	private long dataCenterId;

	@Column(name = "gateway")
	private String gateway;

	@Column(name = "cidr_address")
	private String cidrAddress;

	@Column(name = "cidr_size")
	private int cidrSize;

	@Column(name = "description")
	private String description;

    @Column(name="allocation_state")
    @Enumerated(value=EnumType.STRING)
    AllocationState allocationState;

	@Column(name = "external_dhcp")
	private Boolean externalDhcp;

    @Column(name=GenericDao.REMOVED_COLUMN)
    private Date removed;

	@Column(name = "uuid")
	private String uuid;

	public HostPodVO(String name, long dcId, String gateway, String cidrAddress, int cidrSize, String description) {
		this.name = name;
		this.dataCenterId = dcId;
		this.gateway = gateway;
		this.cidrAddress = cidrAddress;
		this.cidrSize = cidrSize;
		this.description = description;
		this.allocationState = Grouping.AllocationState.Enabled;
		this.externalDhcp = false;
		this.uuid = UUID.randomUUID().toString();
	}

	/*
	 * public HostPodVO(String name, long dcId) { this(null, name, dcId); }
	 */
	protected HostPodVO() {
		this.uuid = UUID.randomUUID().toString();
	}

	@Override
    public long getId() {
		return id;
	}

	public long getDataCenterId() {
		return dataCenterId;
	}

	public void setDataCenterId(long dataCenterId) {
		this.dataCenterId = dataCenterId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
    public String getCidrAddress() {
		return cidrAddress;
	}

	public void setCidrAddress(String cidrAddress) {
		this.cidrAddress = cidrAddress;
	}

	@Override
    public int getCidrSize() {
		return cidrSize;
	}

	public void setCidrSize(int cidrSize) {
		this.cidrSize = cidrSize;
	}

	@Override
    public String getGateway() {
		return gateway;
	}

	public void setGateway(String gateway) {
		this.gateway = gateway;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

    public AllocationState getAllocationState() {
    	return allocationState;
    }

    public void setAllocationState(AllocationState allocationState) {
		this.allocationState = allocationState;
    }

	// Use for comparisons only.
	public HostPodVO(Long id) {
	    this.id = id;
	}

	@Override
    public int hashCode() {
	    return  NumbersUtil.hash(id);
	}

	public boolean getExternalDhcp() {
		return externalDhcp;
	}

	public void setExternalDhcp(boolean use) {
		externalDhcp = use;
	}

	@Override
    public boolean equals(Object obj) {
	    if (obj instanceof HostPodVO) {
	        return id == ((HostPodVO)obj).id;
	    } else {
	        return false;
	    }
	}

    public Date getRemoved() {
        return removed;
    }

    @Override
    public String getUuid() {
    	return this.uuid;
    }

    public void setUuid(String uuid) {
    	this.uuid = uuid;
    }
}
