// 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.resource;

import java.util.HashMap;
import java.util.Map;

import javax.naming.ConfigurationException;

import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.utils.net.MacAddress;
import com.cloud.vm.VirtualMachine;

public class DummyHostServerResource extends ServerResourceBase {

	private String _name;
	private String _zone;
	private String _pod;
	private String _guid;
	private String _url;
	private int _instanceId;
	private final int _prefix = 0x55;
	
	private static volatile int s_nextSequence = 1;
	
	@Override
	protected String getDefaultScriptsDir() {
		return "/dummy";
	}

	@Override
	public Answer executeRequest(Command cmd) {
		return new Answer(cmd, false, "Unsupported in dummy host server resource");
	}

	@Override
	public PingCommand getCurrentStatus(long id) {
        HashMap<String, VirtualMachine.State> newStates = new HashMap<String, VirtualMachine.State>();
        return new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, newStates);
	}

	@Override
	public Type getType() {
        return com.cloud.host.Host.Type.Routing;
	}

	@Override
	public StartupCommand[] initialize() {
		
        StartupRoutingCommand cmd = new StartupRoutingCommand();
        cmd.setCpus(1);
        cmd.setSpeed(1000L);
        cmd.setMemory(1000000L);
        cmd.setDom0MinMemory(256L);
        cmd.setCaps("hvm");
        cmd.setGuid(_guid);
        cmd.setDataCenter(_zone);
        cmd.setPod(_pod);
        cmd.setHypervisorType(HypervisorType.None);
        cmd.setAgentTag("vmops-simulator");
        cmd.setName(_url);
        cmd.setPrivateIpAddress(this.getHostPrivateIp());
        cmd.setPrivateMacAddress(this.getHostMacAddress().toString());
        cmd.setPrivateNetmask("255.255.0.0");
        cmd.setIqn("iqn:"+_url);
        cmd.setStorageIpAddress(getHostStoragePrivateIp());
        cmd.setStorageMacAddress(getHostStorageMacAddress().toString());
        cmd.setStorageIpAddressDeux(getHostStoragePrivateIp2());
        cmd.setStorageMacAddressDeux(getHostStorageMacAddress2().toString());
        cmd.setPublicIpAddress(getHostStoragePrivateIp());
        cmd.setPublicMacAddress(getHostStorageMacAddress().toString());
        cmd.setPublicNetmask("255.255.0.0");
        cmd.setVersion("1.0");

        return new StartupCommand[] {cmd};
	}
	
    @Override
    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
        _name = name;
        _guid = (String)params.get("guid");
        _zone = (String)params.get("zone");
        _pod = (String)params.get("pod");
        _url = (String)params.get("url");
        
        _instanceId = getNextSequenceId();
        return true;
    }
    
    public static int getNextSequenceId() {
    	return s_nextSequence++;
    }
    
	public MacAddress getHostMacAddress() {
		long address = 0;
		
		address = (_prefix & 0xff);
		address <<= 40;
		address |= _instanceId;
		return new MacAddress(address);
	}
	
	public String getHostPrivateIp() {
		int id = _instanceId;
		
		return "172.16." +
			String.valueOf((id >> 8) & 0xff) + "." +
			String.valueOf(id & 0xff);
	}
	
	public MacAddress getHostStorageMacAddress() {
		long address = 0;
		
		address = (_prefix & 0xff);
		address <<= 40;
		address |= (_instanceId | (1L << 31)) & 0xffffffff;
		return new MacAddress(address);
	}
	
	public MacAddress getHostStorageMacAddress2() {
		long address = 0;
		
		address = (_prefix & 0xff);
		address <<= 40;
		address |= (_instanceId | (3L << 30)) & 0xffffffff;
		return new MacAddress(address);
	}
	
	public String getHostStoragePrivateIp() {
		int id = _instanceId;
		id |= 1 << 15;
		
		return "172.16." +
			String.valueOf((id >> 8) & 0xff) + "." +
			String.valueOf(id & 0xff);
	}
	
	public String getHostStoragePrivateIp2() {
		int id = _instanceId;
		id |= 3 << 14;
		
		return "172.16." +
			String.valueOf((id >> 8) & 0xff) + "." +
			String.valueOf((id) & 0xff);
	}
}
