// 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.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 org.apache.cloudstack.api.Identity;
import com.cloud.utils.net.Ip;
import org.apache.cloudstack.api.InternalIdentity;

/**
 * A bean representing a public IP Address
 *
 */
@Entity
@Table(name=("user_ip_address"))
public class IPAddressVO implements IpAddress {
    @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;

    @Column(name="vpc_id")
    private Long vpcId;

	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;
	}

	@Override
    public Long getVpcId() {
        return vpcId;
    }

	@Override
    public void setVpcId(Long vpcId) {
        this.vpcId = vpcId;
    }
}
