// 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.Map;
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.TableGenerator;
import javax.persistence.Transient;

import com.cloud.api.Identity;
import com.cloud.network.Network.Provider;
import com.cloud.org.Grouping;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao;

@Entity
@Table(name="data_center")
public class DataCenterVO implements DataCenter, Identity {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private long id;
    
	@Column(name="name")
	private String name = null;
    
    @Column(name="description")
    private String description = null;
    
    @Column(name="dns1")
    private String dns1 = null;
    
    @Column(name="dns2")
    private String dns2 = null;
    
    @Column(name="internal_dns1")
    private String internalDns1 = null;
    
    @Column(name="internal_dns2")
    private String internalDns2 = null;
    
    @Column(name="router_mac_address", updatable = false, nullable=false)
    private String routerMacAddress = "02:00:00:00:00:01";
    
    @Column(name="guest_network_cidr")
    private String guestNetworkCidr = null;
    
    @Column(name="domain_id")
    private Long domainId = null;

    @Column(name="domain")
    private String domain;
    
    @Column(name="networktype")
    @Enumerated(EnumType.STRING) 
    NetworkType networkType;
    
    @Column(name="dns_provider")
    private String dnsProvider;
    
    @Column(name="dhcp_provider")
    private String dhcpProvider;
    
    @Column(name="gateway_provider")
    private String gatewayProvider;
    
    @Column(name="vpn_provider")
    private String vpnProvider;
    
    @Column(name="userdata_provider")
    private String userDataProvider;
    
    @Column(name="lb_provider")
    private String loadBalancerProvider;
    
    @Column(name="firewall_provider")
    private String firewallProvider;
    
    @Column(name="mac_address", updatable = false, nullable=false)
    @TableGenerator(name="mac_address_sq", table="data_center", pkColumnName="id", valueColumnName="mac_address", allocationSize=1)
    private long macAddress = 1;
    
	@Column(name="zone_token")
	private String zoneToken;    
	
    @Column(name=GenericDao.REMOVED_COLUMN)
    private Date removed;
    
    // This is a delayed load value.  If the value is null,
    // then this field has not been loaded yet.
    // Call the dao to load it.
    @Transient
    Map<String, String> details;
    
    @Column(name="allocation_state")
    @Enumerated(value=EnumType.STRING)
    AllocationState allocationState;

	@Column(name="uuid")
	private String uuid;    
    
    @Column(name="is_security_group_enabled")
    boolean securityGroupEnabled;
    
    @Override
    public String getDnsProvider() {
        return dnsProvider;
    }

    public void setDnsProvider(String dnsProvider) {
        this.dnsProvider = dnsProvider;
    }

    @Override
    public String getDhcpProvider() {
        return dhcpProvider;
    }

    public void setDhcpProvider(String dhcpProvider) {
        this.dhcpProvider = dhcpProvider;
    }

    @Override
    public String getGatewayProvider() {
        return gatewayProvider;
    }

    public void setGatewayProvider(String gatewayProvider) {
        this.gatewayProvider = gatewayProvider;
    }

    @Override
    public String getLoadBalancerProvider() {
        return loadBalancerProvider;
    }

    public void setLoadBalancerProvider(String loadBalancerProvider) {
        this.loadBalancerProvider = loadBalancerProvider;
    }

    @Override
    public String getFirewallProvider() {
        return firewallProvider; 
    }

    public void setFirewallProvider(String firewallProvider) {
        this.firewallProvider = firewallProvider;
    }
    
    public DataCenterVO(long id, String name, String description, String dns1, String dns2, String dns3, String dns4,String guestCidr, String domain, Long domainId, NetworkType zoneType, String zoneToken, String domainSuffix) {
        this(name, description, dns1, dns2, dns3, dns4, guestCidr, domain, domainId, zoneType, zoneToken, domainSuffix, false);
        this.id = id;
        this.allocationState = Grouping.AllocationState.Enabled;
        this.uuid = UUID.randomUUID().toString();
	}

    public DataCenterVO(String name, String description, String dns1, String dns2, String dns3, String dns4, String guestCidr, String domain, Long domainId, NetworkType zoneType, String zoneToken, String domainSuffix, boolean securityGroupEnabled) {
        this.name = name;
        this.description = description;
        this.dns1 = dns1;
        this.dns2 = dns2;
        this.internalDns1 = dns3;
        this.internalDns2 = dns4;
        this.guestNetworkCidr = guestCidr;
        this.domain = domain;
        this.domainId = domainId;
        this.networkType = zoneType;
        this.allocationState = Grouping.AllocationState.Enabled;
        this.securityGroupEnabled = securityGroupEnabled;
        
        
        if (zoneType == NetworkType.Advanced) {
            loadBalancerProvider = Provider.VirtualRouter.getName();
            firewallProvider = Provider.VirtualRouter.getName();
            dhcpProvider = Provider.VirtualRouter.getName();
            dnsProvider = Provider.VirtualRouter.getName();
            gatewayProvider = Provider.VirtualRouter.getName();
            vpnProvider = Provider.VirtualRouter.getName();
            userDataProvider = Provider.VirtualRouter.getName();
        } else if (zoneType == NetworkType.Basic){
            dhcpProvider = Provider.VirtualRouter.getName();
            dnsProvider = Provider.VirtualRouter.getName();
            userDataProvider = Provider.VirtualRouter.getName();
            loadBalancerProvider = Provider.ElasticLoadBalancerVm.getName();
        }

        this.zoneToken = zoneToken;
        this.domain = domainSuffix;
        this.uuid = UUID.randomUUID().toString();
    }
    
    @Override
    public String getVpnProvider() {
        return vpnProvider;
    }

    public void setVpnProvider(String vpnProvider) {
        this.vpnProvider = vpnProvider;
    }

    @Override
    public String getUserDataProvider() {
        return userDataProvider;
    }

    public void setUserDataProvider(String userDataProvider) {
        this.userDataProvider = userDataProvider;
    }
    
    @Override
    public String getGuestNetworkCidr()
    {
    	return guestNetworkCidr;
    }
    
    public void setGuestNetworkCidr(String guestNetworkCidr)
    {
    	this.guestNetworkCidr = guestNetworkCidr;
    }

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

	public void setDomainId(Long domainId) {
		this.domainId = domainId;
	}
    
    @Override
    public String getDescription() {
        return description;
    }

    public String getRouterMacAddress() {
        return routerMacAddress;
    }
    
    @Override
    public String getDns1() {
        return dns1;
    }
    
    @Override
    public String getDns2() {
        return dns2;
    }

    @Override
    public String getInternalDns1() {
        return internalDns1;
    }

    @Override
    public String getInternalDns2() {
        return internalDns2;
    }

	protected DataCenterVO() {
    }

	@Override
    public long getId() {
		return id;
	}
	
	@Override
    public String getName() {
	    return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setDns1(String dns1) {
		this.dns1 = dns1;
	}
	
	public void setDns2(String dns2) {
		this.dns2 = dns2;
	}
	
	public void setInternalDns1(String dns3) {
		this.internalDns1 = dns3;
	}
	
	public void setInternalDns2(String dns4) {
		this.internalDns2 = dns4;
	}

    public void setRouterMacAddress(String routerMacAddress) {
        this.routerMacAddress = routerMacAddress;
    }
    
    @Override
    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }
    
    public void setNetworkType(NetworkType zoneNetworkType) {
        this.networkType = zoneNetworkType;
    }

    @Override
    public NetworkType getNetworkType() {
        return networkType;
    }
    
    @Override 
    public boolean isSecurityGroupEnabled() {
        return securityGroupEnabled;
    }
    
    public void setSecurityGroupEnabled(boolean enabled) {
        this.securityGroupEnabled = enabled;
    }
    
    @Override
    public Map<String, String> getDetails() {
        return details;
    }

    @Override
    public void setDetails(Map<String, String> details2) {
        details = details2;        
    }
    
    public String getDetail(String name) {
        assert (details != null) : "Did you forget to load the details?";
        
        return details != null ? details.get(name) : null;
    }
    
    public void setDetail(String name, String value) {
        assert (details != null) : "Did you forget to load the details?";
        
        details.put(name, value);
    }
    
    public AllocationState getAllocationState() {
    	return allocationState;
    }
    
    public void setAllocationState(AllocationState allocationState) {
		this.allocationState = allocationState;
    }
    
    @Override
    public int hashCode() {
        return NumbersUtil.hash(id);
    }
    
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof DataCenterVO)) {
            return false;
        }
        DataCenterVO that = (DataCenterVO)obj;
        return this.id == that.id;
    }

    @Override
    public String getZoneToken() {
 	    return zoneToken;
 	}
 	
 	public void setZoneToken(String zoneToken) {
 		this.zoneToken = zoneToken;
 	}
 	
 	public Date getRemoved() {
 	    return removed;
 	}
 	
 	@Override
 	public String getUuid() {
 		return this.uuid;
 	}
 	
 	public void setUuid(String uuid) {
 		this.uuid = uuid;
 	}
}
