// 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.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);
	}
}
