// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License.  Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
// 
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network;

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 javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import com.cloud.api.Identity;
import com.cloud.utils.net.Ip;

/**
 * A bean representing a public IP Address
 *
 */
@Entity
@Table(name=("user_ip_address"))
public class IPAddressVO implements IpAddress, Identity {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    long id;
    
	@Column(name="account_id")
	private Long allocatedToAccountId = null;

    @Column(name="domain_id")
    private Long allocatedInDomainId = null;

	@Id
	@Column(name="public_ip_address")
	@Enumerated(value=EnumType.STRING)
	private Ip address = null;

	@Column(name="data_center_id", updatable=false)
	private long dataCenterId;
	
	@Column(name="source_nat")
	private boolean sourceNat;

	@Column(name="allocated")
	@Temporal(value=TemporalType.TIMESTAMP)
	private Date allocatedTime;
	
	@Column(name="vlan_db_id")
	private long vlanId;

	@Column(name="one_to_one_nat")
	private boolean oneToOneNat;
	
	@Column(name="vm_id")
    private Long associatedWithVmId;
	
	@Column(name="state")
	private State state;
	
	@Column(name="mac_address")
	private long macAddress;
	
	@Column(name="source_network_id")
    private Long sourceNetworkId;
	
	@Column(name="network_id")
	private Long associatedWithNetworkId;
	
	@Column(name="uuid")
	private String uuid;
	
    @Column(name="physical_network_id")
    private Long physicalNetworkId;
    
    @Column(name="is_system")
    private boolean system;
    
	@Column(name="account_id")
	@Transient
	private Long accountId = null;
	
	@Transient
    @Column(name="domain_id")
    private Long domainId = null;

	protected IPAddressVO() {
		this.uuid = UUID.randomUUID().toString();
	}
	
	@Override
    public boolean readyToUse() {
	    return state == State.Allocated;
	}

	public IPAddressVO(Ip address, long dataCenterId, long macAddress, long vlanDbId, boolean sourceNat) {
		this.address = address;
		this.dataCenterId = dataCenterId;
		this.vlanId = vlanDbId;
		this.sourceNat = sourceNat;
		this.allocatedInDomainId = null;
		this.allocatedToAccountId = null;
		this.allocatedTime = null;
		this.state = State.Free;
		this.macAddress = macAddress;
		this.uuid = UUID.randomUUID().toString();
	}
	
    public long getMacAddress() {
	    return macAddress;
	}
	
	@Override
    public long getDataCenterId() {
	    return dataCenterId; 
	}

	@Override
    public Ip getAddress() {
		return address;
	}
	
	@Override
    public Long getAllocatedToAccountId() {
		return allocatedToAccountId;
	}
	
    @Override
    public Long getAllocatedInDomainId() {
        return allocatedInDomainId;
    }
	
	@Override
	public Long getAssociatedWithNetworkId() {
	    return associatedWithNetworkId;
	}
	
	public void setAssociatedWithNetworkId(Long networkId) {
	    this.associatedWithNetworkId = networkId;
	}

	@Override
    public Long getAssociatedWithVmId() {
        return associatedWithVmId;
    }

    public void setAssociatedWithVmId(Long associatedWithVmId) {
        this.associatedWithVmId = associatedWithVmId;
    }
    
	@Override
    public Date getAllocatedTime() {
		return allocatedTime;
	}

    public void setAllocatedToAccountId(Long accountId) {
		this.allocatedToAccountId = accountId;
	}

    public void setAllocatedInDomainId(Long domainId) {
        this.allocatedInDomainId = domainId;
    }

    public void setSourceNat(boolean sourceNat) {
		this.sourceNat = sourceNat;
	}
	
	@Override
    public boolean isSourceNat() {
		return sourceNat;
	}

    public void setAllocatedTime(Date allocated) {
		this.allocatedTime = allocated;
	}
	
	@Override
    public long getVlanId() {
		return this.vlanId;
	}
	
    public void setVlanId(long vlanDbId) {
		this.vlanId = vlanDbId;
	}

	@Override
    public boolean isOneToOneNat() {
		return oneToOneNat;
	}

    public void setOneToOneNat(boolean oneToOneNat) {
		this.oneToOneNat = oneToOneNat;
	}
    
    @Override
    public long getDomainId() {
        return allocatedInDomainId == null ? -1 : allocatedInDomainId;
    }
    
    @Override
    public long getAccountId() {
        return allocatedToAccountId == null ? -1 : allocatedToAccountId;
    }
    
    @Override
    public State getState() {
        return state;
    }
    
    public void setState(State state) {
        this.state = state;
    }
	
	@Override
    public String toString() {
	    return new StringBuilder("Ip[").append(address).append("-").append(dataCenterId).append("]").toString();
	}
	
	@Override
    public long getId() {
        return id;
    }

    public Long getSourceNetworkId() {
        return sourceNetworkId;
    }

    public void setSourceNetworkId(Long sourceNetworkId) {
        this.sourceNetworkId = sourceNetworkId;
    }
    
    @Override
    public String getUuid() {
    	return this.uuid;
    }
    
    public void setUuid(String uuid) {
    	this.uuid = uuid;
    }

    public Long getPhysicalNetworkId() {
        return physicalNetworkId;
    }

    public void setPhysicalNetworkId(Long physicalNetworkId) {
        this.physicalNetworkId = physicalNetworkId;
    }
    
    @Override
	public boolean getSystem() {
		return system;
	}

	public void setSystem(boolean isSystem) {
		this.system = isSystem;
	}
}
