// 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.baremetal;

import java.util.HashMap;
import java.util.Map;

import javax.ejb.Local;
import javax.naming.ConfigurationException;

import org.apache.log4j.Logger;

import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckNetworkAnswer;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.MigrateAnswer;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev;
import com.cloud.agent.api.baremetal.IpmiBootorResetCommand;
import com.cloud.agent.api.to.VirtualMachineTO;
import org.apache.cloudstack.api.ApiConstants;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.resource.ServerResource;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script;
import com.cloud.utils.script.Script2;
import com.cloud.utils.script.Script2.ParamType;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;

@Local(value = ServerResource.class)
public class BareMetalResourceBase implements ServerResource {
	private static final Logger s_logger = Logger.getLogger(BareMetalResourceBase.class);
    protected HashMap<String, State> _vms = new HashMap<String, State>(2);
	protected String _name;
	protected String _uuid;
	protected String _zone;
    protected String _pod;
    protected String _cluster;
    protected long _memCapacity;
    protected long _cpuCapacity;
    protected long _cpuNum;
    protected String _mac;
    protected String _username;
    protected String _password;
    protected String _ip;
    protected IAgentControl _agentControl;
    protected Script2 _pingCommand;
    protected Script2 _setPxeBootCommand;
    protected Script2 _setDiskBootCommand;
    protected Script2 _rebootCommand;
    protected Script2 _getStatusCommand;
    protected Script2 _powerOnCommand;
    protected Script2 _powerOffCommand;
    protected Script2 _forcePowerOffCommand;
    protected Script2 _bootOrRebootCommand;
    protected String _vmName;

    private void changeVmState(String vmName, VirtualMachine.State state) {
        synchronized (_vms) {
            _vms.put(vmName, state);
        }
    }
    
    private State removeVmState(String vmName) {
        synchronized (_vms) {
            return _vms.remove(vmName);
        }
    }
    
	@Override
	public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
		_name = name;
		_uuid = (String) params.get("guid");
		try {
			_memCapacity = Long.parseLong((String)params.get(ApiConstants.MEMORY)) * 1024L * 1024L;
			_cpuCapacity = Long.parseLong((String)params.get(ApiConstants.CPU_SPEED));
			_cpuNum = Long.parseLong((String)params.get(ApiConstants.CPU_NUMBER));
		} catch (NumberFormatException e) {
			throw new ConfigurationException(String.format("Unable to parse number of CPU or memory capacity " +
					"or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", (String)params.get(ApiConstants.CPU_NUMBER),
					(String)params.get(ApiConstants.MEMORY), (String)params.get(ApiConstants.CPU_SPEED)));
		}
		
		_zone = (String) params.get("zone");
		_pod = (String) params.get("pod");
		_cluster = (String) params.get("cluster");
		_ip = (String)params.get(ApiConstants.PRIVATE_IP);
		_mac = (String)params.get(ApiConstants.HOST_MAC);
		_username = (String)params.get(ApiConstants.USERNAME);
		_password = (String)params.get(ApiConstants.PASSWORD);
		_vmName = (String)params.get("vmName");
		
		if (_pod == null) {
            throw new ConfigurationException("Unable to get the pod");
        }

		if (_cluster == null) {
            throw new ConfigurationException("Unable to get the pod");
        }
		
        if (_ip == null) {
            throw new ConfigurationException("Unable to get the host address");
        }
        
        if (_mac.equalsIgnoreCase("unknown")) {
            throw new ConfigurationException("Unable to get the host mac address");
        }
        
        if (_mac.split(":").length != 6) {
            throw new ConfigurationException("Wrong MAC format(" + _mac + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive");
        }
        
        if (_uuid == null) {
            throw new ConfigurationException("Unable to get the uuid");
        }
		
        String injectScript = "scripts/util/ipmi.py";
		String scriptPath = Script.findScript("", injectScript);
		if (scriptPath == null) {
			 throw new ConfigurationException("Cannot find ping script " + scriptPath);
		}
		_pingCommand = new Script2(scriptPath, s_logger);
		_pingCommand.add("ping");
		_pingCommand.add("hostname="+_ip);
		_pingCommand.add("usrname="+_username);
		_pingCommand.add("password="+_password, ParamType.PASSWORD);
		
		_setPxeBootCommand = new Script2(scriptPath, s_logger);
		_setPxeBootCommand.add("boot_dev");
		_setPxeBootCommand.add("hostname="+_ip);
		_setPxeBootCommand.add("usrname="+_username);
		_setPxeBootCommand.add("password="+_password, ParamType.PASSWORD);
		_setPxeBootCommand.add("dev=pxe");
		
		_setDiskBootCommand = new Script2(scriptPath, s_logger);
		_setDiskBootCommand.add("boot_dev");
		_setDiskBootCommand.add("hostname="+_ip);
		_setDiskBootCommand.add("usrname="+_username);
		_setDiskBootCommand.add("password="+_password, ParamType.PASSWORD);
		_setDiskBootCommand.add("dev=disk");
		
		_rebootCommand = new Script2(scriptPath, s_logger);
		_rebootCommand.add("reboot");
		_rebootCommand.add("hostname="+_ip);
		_rebootCommand.add("usrname="+_username);
		_rebootCommand.add("password="+_password, ParamType.PASSWORD);
		
		_getStatusCommand = new Script2(scriptPath, s_logger);
		_getStatusCommand.add("ping");
		_getStatusCommand.add("hostname="+_ip);
		_getStatusCommand.add("usrname="+_username);
		_getStatusCommand.add("password="+_password, ParamType.PASSWORD);
		
		_powerOnCommand = new Script2(scriptPath, s_logger);
		_powerOnCommand.add("power");
		_powerOnCommand.add("hostname="+_ip);
		_powerOnCommand.add("usrname="+_username);
		_powerOnCommand.add("password="+_password, ParamType.PASSWORD);
		_powerOnCommand.add("action=on");
		
		_powerOffCommand = new Script2(scriptPath, s_logger);
		_powerOffCommand.add("power");
		_powerOffCommand.add("hostname="+_ip);
		_powerOffCommand.add("usrname="+_username);
		_powerOffCommand.add("password="+_password, ParamType.PASSWORD);
		_powerOffCommand.add("action=soft");
		
        _forcePowerOffCommand = new Script2(scriptPath, s_logger);
        _forcePowerOffCommand.add("power");
        _forcePowerOffCommand.add("hostname=" + _ip);
        _forcePowerOffCommand.add("usrname=" + _username);
        _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD);
        _forcePowerOffCommand.add("action=off");

		_bootOrRebootCommand = new Script2(scriptPath, s_logger);
		_bootOrRebootCommand.add("boot_or_reboot");
		_bootOrRebootCommand.add("hostname="+_ip);
		_bootOrRebootCommand.add("usrname="+_username);
		_bootOrRebootCommand.add("password="+_password, ParamType.PASSWORD);
		
		return true;
	}

	protected boolean doScript(Script cmd) {
		return doScript(cmd, null);
	}
	
	protected boolean doScript(Script cmd, OutputInterpreter interpreter) {
		int retry = 5;
		String res = null;
		while (retry-- > 0) {
			if (interpreter == null) {
			res = cmd.execute();
			} else {
				res = cmd.execute(interpreter);
			}
			if (res != null && res.startsWith("Error: Unable to establish LAN")) {
				s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times");
				continue;
			} else if (res == null) {
				return true;
			} else {
				break;
			}
		}
		
		s_logger.warn("IPMI Scirpt failed due to " + res + "(" + cmd.toString() +")");
		return false;
	}
	
	@Override
	public boolean start() {		
		return true;
	}

	@Override
	public boolean stop() {	
		return true;
	}

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

	@Override
	public Type getType() {
		return com.cloud.host.Host.Type.Routing;
	}

	protected State getVmState() {
        OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
        if (!doScript(_getStatusCommand, interpreter)) {
            s_logger.warn("Cannot get power status of " + _name + ", assume VM state was not changed");
            return null;
        }
        if (isPowerOn(interpreter.getLines())) {
            return State.Running;
        } else {
            return State.Stopped;
        }
	}
	
	protected Map<String, State> fullSync() {
		Map<String, State> changes = new HashMap<String, State>();

		if (_vmName != null) {
		    State state = getVmState();
		    if (state != null) {
		        changes.put(_vmName, state);
		    }
		}
		
		return changes;
	}
	
	@Override
	public StartupCommand[] initialize() {
		StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal,
				new HashMap<String, String>(), null);
		cmd.setDataCenter(_zone);
		cmd.setPod(_pod);
		cmd.setCluster(_cluster);
		cmd.setGuid(_uuid);
		cmd.setName(_ip);
		cmd.setPrivateIpAddress(_ip);
		cmd.setStorageIpAddress(_ip);
		cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion());
		cmd.setCpus((int)_cpuNum);
		cmd.setSpeed(_cpuCapacity);
		cmd.setMemory(_memCapacity);
		cmd.setPrivateMacAddress(_mac);
		cmd.setPublicMacAddress(_mac);
		cmd.setStateChanges(fullSync());
		return new StartupCommand[] {cmd};
	}

	private boolean ipmiPing() {
		return doScript(_pingCommand);
	}
	
	@Override
	public PingCommand getCurrentStatus(long id) {
		try {
			if (!ipmiPing()) {
				Thread.sleep(1000);
				if (!ipmiPing()) {
					s_logger.warn("Cannot ping ipmi nic " + _ip);
					return null;
				}
			}
		} catch (Exception e) {
			s_logger.debug("Cannot ping ipmi nic " + _ip, e);
			return null;
		}
		 
		return new PingRoutingCommand(getType(), id, deltaSync());
	}

	protected Answer execute(IpmISetBootDevCommand cmd) {
		Script bootCmd = null;
		if (cmd.getBootDev() == BootDev.disk) {
			bootCmd = _setDiskBootCommand;
		} else if (cmd.getBootDev() == BootDev.pxe) {
			bootCmd = _setPxeBootCommand;
		} else {
			throw new CloudRuntimeException("Unkonwn boot dev " + cmd.getBootDev());
		}
		
		String bootDev = cmd.getBootDev().name();
		if (!doScript(bootCmd)) {
			s_logger.warn("Set " + _ip + " boot dev to " + bootDev + "failed");
			return new Answer(cmd, false, "Set " + _ip + " boot dev to " + bootDev + "failed");
		}
		
		s_logger.warn("Set " + _ip + " boot dev to " + bootDev + "Success");
		return new Answer(cmd, true, "Set " + _ip + " boot dev to " + bootDev + "Success");
	}
	
	protected MaintainAnswer execute(MaintainCommand cmd) {
		return new MaintainAnswer(cmd, false);
	}
	
	protected PrepareForMigrationAnswer execute(PrepareForMigrationCommand cmd) {
		return new PrepareForMigrationAnswer(cmd);
	}
	
	protected MigrateAnswer execute(MigrateCommand cmd) {   
		if (!doScript(_powerOffCommand)) {
			return new MigrateAnswer(cmd, false, "IPMI power off failed", null);
		}
		return new MigrateAnswer(cmd, true, "success", null);
	}
	
	protected CheckVirtualMachineAnswer execute(final CheckVirtualMachineCommand cmd) {
		return new CheckVirtualMachineAnswer(cmd, State.Stopped, null);
	}
	
	protected Answer execute(IpmiBootorResetCommand cmd) {
	    if (!doScript(_bootOrRebootCommand)) {
	        return new Answer(cmd ,false, "IPMI boot or reboot failed");
	    }
	    return new Answer(cmd, true, "Success");
	    
	}
	
	protected CheckNetworkAnswer execute(CheckNetworkCommand cmd) {
		return new CheckNetworkAnswer(cmd, true, "Success");
	}
	
	@Override
	public Answer executeRequest(Command cmd) {
		if (cmd instanceof ReadyCommand) {
			return execute((ReadyCommand)cmd);
		} else if (cmd instanceof StartCommand) {
			return execute((StartCommand)cmd);
		} else if (cmd instanceof StopCommand) {
			return execute((StopCommand)cmd);
		} else if (cmd instanceof RebootCommand) {
			return execute((RebootCommand)cmd);
		} else if (cmd instanceof IpmISetBootDevCommand) {
			return execute((IpmISetBootDevCommand)cmd);
		} else if (cmd instanceof MaintainCommand) {
			return execute((MaintainCommand)cmd);
		} else if (cmd instanceof PrepareForMigrationCommand) {
			return execute((PrepareForMigrationCommand)cmd);
		} else if (cmd instanceof MigrateCommand) {
			return execute((MigrateCommand)cmd);
		} else if (cmd instanceof CheckVirtualMachineCommand) {
			return execute((CheckVirtualMachineCommand)cmd);
		} else if (cmd instanceof IpmiBootorResetCommand) {
		    return execute((IpmiBootorResetCommand)cmd);
		} else if (cmd instanceof CheckNetworkCommand) {
			return execute((CheckNetworkCommand)cmd);
		} else {
			return Answer.createUnsupportedCommandAnswer(cmd);
		}
	}

	protected boolean isPowerOn(String str) {
		if (str.startsWith("Chassis Power is on")) {
			return true;
		} else if (str.startsWith("Chassis Power is off")) {
			return false;
		} else {
			throw new CloudRuntimeException("Cannot parse IPMI power status " + str);
		}
	}
	
	protected RebootAnswer execute(final RebootCommand cmd) {
		if (!doScript(_rebootCommand)) {
			return new RebootAnswer(cmd, "IPMI reboot failed", false);
		}
		
		return new RebootAnswer(cmd, "reboot succeeded", true);
	}
	
	protected StopAnswer execute(final StopCommand cmd) {
        boolean success = false;
        int count = 0;
        Script powerOff = _powerOffCommand;
        
        while (count < 10) {
            if (!doScript(powerOff)) {
                break;
            }
            
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                break;
            }
            
            OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
            if (!doScript(_getStatusCommand, interpreter)) {
                s_logger.warn("Cannot get power status of " + _name + ", assume VM state was not changed");
                break;
            }
            
            if (!isPowerOn(interpreter.getLines())) {
                success = true;
                break;
            } else {
                powerOff = _forcePowerOffCommand;
            }
                        
            count++;
        }
        		
		return success ? new StopAnswer(cmd, "Success", null, true) : new StopAnswer(cmd, "IPMI power off failed", false);
	}

	protected StartAnswer execute(StartCommand cmd) {
		VirtualMachineTO vm = cmd.getVirtualMachine();
		State state = State.Stopped;
		
		try {
            changeVmState(vm.getName(), State.Starting);

            boolean pxeBoot = false;
            String[] bootArgs = vm.getBootArgs().split(" ");
            for (int i = 0; i < bootArgs.length; i++) {
                if (bootArgs[i].equalsIgnoreCase("PxeBoot")) {
                    pxeBoot = true;
                    break;
                }
            }

            if (pxeBoot) {
                if (!doScript(_setPxeBootCommand)) {
                    return new StartAnswer(cmd, "Set boot device to PXE failed");
                }
                s_logger.debug("Set " + vm.getHostName() + " to PXE boot successfully");
            } else {
                execute(new IpmISetBootDevCommand(BootDev.disk));
            }

            OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
            if (!doScript(_getStatusCommand, interpreter)) {
                return new StartAnswer(cmd, "Cannot get current power status of " + _name);
            }

            if (isPowerOn(interpreter.getLines())) {
                if (pxeBoot) {
                    if (!doScript(_rebootCommand)) {
                        return new StartAnswer(cmd, "IPMI reboot failed");
                    }
                    s_logger.debug("IPMI reboot " + vm.getHostName() + " successfully");
                } else {
                    s_logger.warn("Machine " + _name + " is alreay power on, why we still get a Start command? ignore it");

                }
            } else {
                if (!doScript(_powerOnCommand)) {
                    return new StartAnswer(cmd, "IPMI power on failed");
                }
            }

            s_logger.debug("Start bare metal vm " + vm.getName() + "successfully");
            state = State.Running;
            _vmName = vm.getName();
            return new StartAnswer(cmd);
		} finally {
		    if (state != State.Stopped) {
		        changeVmState(vm.getName(), state);
		    } else {
		        removeVmState(vm.getName());
		    }
		}
	}
	
	protected HashMap<String, State> deltaSync() {
        final HashMap<String, State> changes = new HashMap<String, State>();
  /*    
   *    Disable sync until we find a way that only tracks status but not does action
   *    
   *    The scenario is: Baremetal will reboot host when creating template. Given most 
   *    servers take a long time to boot up, there would be a period that mgmt server finds
   *    the host is stopped through fullsync. Then mgmt server updates database with marking the host as
   *    stopped, after that, the host comes up and full sync then indicates it's running. Because
   *    in database the host is already stopped, mgmt server sends out a stop command.
   *    As a result, creating image gets never happened.
   *      
        if (_vmName == null) {
            return null;
        }
        
        State newState = getVmState();
        if (newState == null) {
            s_logger.warn("Cannot get power state of VM " + _vmName);
            return null;
        }
        
        final State oldState = removeVmState(_vmName);
        if (oldState == null) {
            changeVmState(_vmName, newState);
            changes.put(_vmName, newState);
        } else if (oldState == State.Starting) {
            if (newState == State.Running) {
                changeVmState(_vmName, newState);
            } else if (newState == State.Stopped) {
                s_logger.debug("Ignoring vm " + _vmName + " because of a lag in starting the vm.");
            }
        } else if (oldState == State.Migrating) {
            s_logger.warn("How can baremetal VM get into migrating state???");
        } else if (oldState == State.Stopping) {
            if (newState == State.Stopped) {
                changeVmState(_vmName, newState);
            } else if (newState == State.Running) {
                s_logger.debug("Ignoring vm " + _vmName + " because of a lag in stopping the vm. ");
            }
        } else if (oldState != newState) {
            changeVmState(_vmName, newState);
            changes.put(_vmName, newState);
        }
       */
        return changes;
       
	}
	
	protected ReadyAnswer execute(ReadyCommand cmd) {
		// derived resource should check if the PXE server is ready 
		s_logger.debug("Bare metal resource " + _name + " is ready");
		return new ReadyAnswer(cmd);
	}
	
	@Override
	public void disconnected() {

	}

	@Override
	public IAgentControl getAgentControl() {
		return _agentControl;
	}

	@Override
	public void setAgentControl(IAgentControl agentControl) {
		_agentControl = agentControl;
	}

	@Override
	public void setName(String name) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setConfigParams(Map<String, Object> params) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Map<String, Object> getConfigParams() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getRunLevel() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void setRunLevel(int level) {
		// TODO Auto-generated method stub
		
	}

}
