// 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.net.URI;
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.Id;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Transient;

import com.cloud.acl.ControlledEntity;
import com.cloud.api.Identity;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.NetUtils;

/**
 * NetworkConfigurationVO contains information about a specific network.
 *
 */
@Entity
@Table(name="networks")
public class NetworkVO implements Network, Identity {
    @Id
    @TableGenerator(name="networks_sq", table="sequence", pkColumnName="name", valueColumnName="value", pkColumnValue="networks_seq", allocationSize=1)
    @Column(name="id")
    long id;

    @Column(name="mode")
    @Enumerated(value=EnumType.STRING)
    Mode mode;

    @Column(name="broadcast_domain_type")
    @Enumerated(value=EnumType.STRING)
    BroadcastDomainType broadcastDomainType;

    @Column(name="traffic_type")
    @Enumerated(value=EnumType.STRING)
    TrafficType trafficType;

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

    @Column(name="display_text")
    String displayText;;

    @Column(name="broadcast_uri")
    URI broadcastUri;

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

    @Column(name="cidr")
    String cidr;

    @Column(name="network_offering_id")
    long networkOfferingId;

    @Column(name="physical_network_id")
    Long physicalNetworkId;
    
    @Column(name="data_center_id")
    long dataCenterId;

    @Column(name="related")
    long related;

    @Column(name="guru_name")
    String guruName;

    @Column(name="state")
    @Enumerated(value=EnumType.STRING)
    State state;

    @Column(name="dns1")
    String dns1;

    @Column(name="domain_id")
    long domainId;

    @Column(name="account_id")
    long accountId;

    @Column(name="set_fields")
    long setFields;

    @TableGenerator(name="mac_address_seq", table="op_networks", pkColumnName="id", valueColumnName="mac_address_seq", allocationSize=1)
    @Transient
    long macAddress = 1;

    @Column(name="guru_data", length=1024)
    String guruData;

    @Column(name="dns2")
    String dns2;

    @Column(name="network_domain")
    String networkDomain;

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

    @Column(name=GenericDao.CREATED_COLUMN)
    Date created;

    @Column(name="reservation_id")
    String reservationId;
    
    @Column(name="uuid")
    String uuid;
    
    @Column(name="guest_type")
    @Enumerated(value=EnumType.STRING)
    Network.GuestType guestType;
    
    @Column(name="acl_type")
    @Enumerated(value=EnumType.STRING)
    ControlledEntity.ACLType aclType;

    @Column(name="restart_required")
    boolean restartRequired = false;
    
    @Column(name="specify_ip_ranges")
    boolean specifyIpRanges = false;
    
    public NetworkVO() {
    	this.uuid = UUID.randomUUID().toString();
    }

    /**
     * Constructor to be used for the adapters because it only initializes what's needed.
     * @param trafficType
     * @param mode
     * @param broadcastDomainType
     * @param networkOfferingId
     * @param state TODO
     * @param dataCenterId
     * @param physicalNetworkId TODO
     */
    public NetworkVO(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, State state, long dataCenterId, Long physicalNetworkId) {
        this.trafficType = trafficType;
        this.mode = mode;
        this.broadcastDomainType = broadcastDomainType;
        this.networkOfferingId = networkOfferingId;
        this.dataCenterId = dataCenterId;
        this.physicalNetworkId = physicalNetworkId;
        if (state == null) {
            state = State.Allocated;
        } else {
            this.state = state;
        }
        this.id = -1;
    	this.uuid = UUID.randomUUID().toString();
    }

    public NetworkVO(long id, Network that, long offeringId, String guruName, long domainId, long accountId, long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges) {
        this(id, that.getTrafficType(), that.getMode(), that.getBroadcastDomainType(), offeringId, domainId, accountId, related, name, displayText, networkDomain, guestType, dcId, physicalNetworkId, aclType, specifyIpRanges);
        this.gateway = that.getGateway();
        this.cidr = that.getCidr();
        this.broadcastUri = that.getBroadcastUri();
        this.broadcastDomainType = that.getBroadcastDomainType();
        this.guruName = guruName;
        this.state = that.getState();
        if (state == null) {
            state = State.Allocated;
        }
    	this.uuid = UUID.randomUUID().toString();
    }

    /**
     * Constructor for the actual DAO object.
     * @param trafficType
     * @param mode
     * @param broadcastDomainType
     * @param networkOfferingId
     * @param domainId
     * @param accountId
     * @param name
     * @param displayText
     * @param networkDomain
     * @param guestType TODO
     * @param aclType TODO
     * @param specifyIpRanges TODO
     * @param dataCenterId
     */
    public NetworkVO(long id, TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long domainId, long accountId, long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges) {
        this(trafficType, mode, broadcastDomainType, networkOfferingId, State.Allocated, dcId, physicalNetworkId);
        this.domainId = domainId;
        this.accountId = accountId;
        this.related = related;
        this.id = id;
        this.name = name;
        this.displayText = displayText;
        this.aclType = aclType;
        this.networkDomain = networkDomain;
    	this.uuid = UUID.randomUUID().toString();
        this.guestType = guestType;
        this.specifyIpRanges = specifyIpRanges;
    }

    @Override
    public String getReservationId() {
        return reservationId;
    }

    public void setReservationId(String reservationId) {
        this.reservationId = reservationId;
    }

    @Override
    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    @Override
    public long getRelated() {
        return related;
    }

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

    @Override
    public Mode getMode() {
        return mode;
    }

    @Override
    public long getAccountId() {
        return accountId;
    }

    @Override
    public long getDomainId() {
        return domainId;
    }

    @Override
    public long getNetworkOfferingId() {
        return networkOfferingId;
    }

    public void setNetworkOfferingId(long networkOfferingId) {
        this.networkOfferingId = networkOfferingId;
    }

    public void setMode(Mode mode) {
        this.mode = mode;
    }

    @Override
    public BroadcastDomainType getBroadcastDomainType() {
        return broadcastDomainType;
    }

    public String getGuruData() {
        return guruData;
    }

    public void setGuruData(String guruData) {
        this.guruData = guruData;
    }

    public String getGuruName() {
        return guruName;
    }

    public void setGuruName(String guruName) {
        this.guruName = guruName;
    }

    public void setBroadcastDomainType(BroadcastDomainType broadcastDomainType) {
        this.broadcastDomainType = broadcastDomainType;
    }

    @Override
    public String getNetworkDomain() {
        return networkDomain;
    }

    public void setNetworkDomain(String networkDomain) {
        this.networkDomain = networkDomain;
    }

    @Override
    public TrafficType getTrafficType() {
        return trafficType;
    }

    public void setTrafficType(TrafficType trafficType) {
        this.trafficType = trafficType;
    }

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

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

    @Override
    public String getCidr() {
        return cidr;
    }

    public void setCidr(String cidr) {
        this.cidr = cidr;
    }

    @Override
    public URI getBroadcastUri() {
        return broadcastUri;
    }

    public void setBroadcastUri(URI broadcastUri) {
        this.broadcastUri = broadcastUri;
    }

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

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

    @Override
    public long getDataCenterId() {
        return dataCenterId;
    }

    public String getDns1() {
        return dns1;
    }

    public void setDns1(String dns) {
        this.dns1 = dns;
    }

    public String getDns2() {
        return dns2;
    }

    public void setDns2(String dns) {
        this.dns2 = dns;
    }

    @Override
    public String getName() {
        return name;
    }

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

    @Override
    public String getDisplayText() {
        return displayText;
    }

    public void setDisplayText(String displayText) {
        this.displayText = displayText;
    }

    public Date getRemoved() {
        return removed;
    }

    public void setRemoved(Date removed) {
        this.removed = removed;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }
    
    @Override
    public Network.GuestType getGuestType() {
        return guestType;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof NetworkVO)) {
            return false;
        }
        NetworkVO that = (NetworkVO)obj;
        if (this.trafficType != that.trafficType) {
            return false;
        }

        if ((this.cidr == null && that.cidr != null) || (this.cidr != null && that.cidr == null)) {
            return false;
        }

        if (this.cidr == null && that.cidr == null) {
            return true;
        }

        return NetUtils.isNetworkAWithinNetworkB(this.cidr, that.cidr);
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder("Ntwk[");
        buf.append(id).append("|").append(trafficType.toString()).append("|").append(networkOfferingId).append("]");
        return buf.toString();
    }


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

	public ControlledEntity.ACLType getAclType() {
		return aclType;
	}

	public void setRestartRequired(boolean restartRequired) {
		this.restartRequired = restartRequired;
	}

	@Override
	public boolean isRestartRequired() {
		return restartRequired;
	}
	
    @Override
    public boolean getSpecifyIpRanges() {
    	return specifyIpRanges;
    }
}
