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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.naming.ConfigurationException;

import org.apache.log4j.Logger;

import com.cloud.agent.Agent.ExitStatus;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartupVMMAgentCommand;
import com.cloud.agent.dao.StorageComponent;
import com.cloud.agent.dao.impl.PropertiesStorage;
import com.cloud.agent.transport.Request;
import com.cloud.resource.ServerResource;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.backoff.BackoffAlgorithm;
import com.cloud.utils.backoff.impl.ConstantTimeBackoff;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.MacAddress;
import com.cloud.utils.nio.HandlerFactory;
import com.cloud.utils.nio.Link;
import com.cloud.utils.nio.NioServer;
import com.cloud.utils.nio.Task;

/**
 * Implementation of agent shell to run the agents on System Center Virtual Machine manager
 **/

public class VmmAgentShell implements IAgentShell, HandlerFactory {

    private static final Logger s_logger = Logger.getLogger(VmmAgentShell.class.getName());
    private final Properties _properties = new Properties();
    private final Map<String, Object> _cmdLineProperties = new HashMap<String, Object>();
    private StorageComponent _storage;
    private BackoffAlgorithm _backoff;
    private String _version;
    private String _zone;
    private String _pod;
    private String _cluster;
    private String _host;
    private String _privateIp;
    private int _port;
    private int _proxyPort;
    private int _workers;
    private String _guid;
    static private NioServer _connection;
    static private int _listenerPort=9000;    
    private int _nextAgentId = 1;
    private volatile boolean _exit = false;
    private int _pingRetries;
    private final Thread _consoleProxyMain = null;
    private final List<Agent> _agents = new ArrayList<Agent>();

    public VmmAgentShell() {
    }

    @Override
    public Properties getProperties() {
        return _properties;
    }

    @Override
    public BackoffAlgorithm getBackoffAlgorithm() {
        return _backoff;
    }

    @Override
    public int getPingRetries() {
        return _pingRetries;
    }

    @Override
    public String getZone() {
        return _zone;
    }

    @Override
    public String getPod() {
        return _pod;
    }

    @Override
    public String getHost() {
        return _host;
    }

    @Override
    public String getPrivateIp() {
        return _privateIp;
    }

    @Override
    public int getPort() {
        return _port;
    }

    @Override
    public int getProxyPort() {
        return _proxyPort;
    }

    @Override
    public int getWorkers() {
        return _workers;
    }

    @Override
    public String getGuid() {
        return _guid;
    }

    @Override
    public void upgradeAgent(String url) {
        // TODO Auto-generated method stub

    }

    @Override
    public String getVersion() {
        return _version;
    }

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

    public String getProperty(String prefix, String name) {
        if(prefix != null)
            return _properties.getProperty(prefix + "." + name);

        return _properties.getProperty(name);
    }

    @Override
    public String getPersistentProperty(String prefix, String name) {
        if(prefix != null)
            return _storage.get(prefix + "." + name);
        return _storage.get(name);
    }

    @Override
    public void setPersistentProperty(String prefix, String name, String value) {
        if(prefix != null)
            _storage.persist(prefix + "." + name, value);
        else
            _storage.persist(name, value);		
    }

    private void loadProperties() throws ConfigurationException {
        final File file = PropertiesUtil.findConfigFile("agent.properties");
        if (file == null) {
            throw new ConfigurationException("Unable to find agent.properties.");
        }

        s_logger.info("agent.properties found at " + file.getAbsolutePath());

        try {
            _properties.load(new FileInputStream(file));
        } catch (final FileNotFoundException ex) {
            throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
        } catch (final IOException ex) {
            throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
        }
    }

    protected boolean parseCommand(final String[] args) throws ConfigurationException {
        String host = null;
        String workers = null;
        String port = null;
        String zone = null;
        String pod = null;
        String guid = null;
        for (int i = 0; i < args.length; i++) {
            final String[] tokens = args[i].split("=");
            if (tokens.length != 2) {
                System.out.println("Invalid Parameter: " + args[i]);
                continue;
            }

            // save command line properties
            _cmdLineProperties.put(tokens[0], tokens[1]);

            if (tokens[0].equalsIgnoreCase("port")) {
                port = tokens[1];
            } else if (tokens[0].equalsIgnoreCase("threads")) {
                workers = tokens[1];
            } else if (tokens[0].equalsIgnoreCase("host")) {
                host = tokens[1];
            } else if(tokens[0].equalsIgnoreCase("zone")) {
                zone = tokens[1];
            } else if(tokens[0].equalsIgnoreCase("pod")) {
                pod = tokens[1];
            } else if(tokens[0].equalsIgnoreCase("guid")) {
                guid = tokens[1];
            } else if(tokens[0].equalsIgnoreCase("eth1ip")) {
                _privateIp = tokens[1];
            }
        }

        if (port == null) {
            port = getProperty(null, "port");
        }

        _port = NumbersUtil.parseInt(port, 8250);

        _proxyPort = NumbersUtil.parseInt(getProperty(null, "consoleproxy.httpListenPort"), 443);

        if (workers == null) {
            workers = getProperty(null, "workers");
        }

        _workers = NumbersUtil.parseInt(workers, 5);

        if (host == null) {
            host = getProperty(null, "host");
        }

        if (host == null) {
            host = "localhost";
        }
        _host = host;

        if(zone != null)
            _zone = zone;
        else
            _zone = getProperty(null, "zone");
        if (_zone == null || (_zone.startsWith("@") && _zone.endsWith("@"))) {
            _zone = "default";
        }

        if(pod != null)
            _pod = pod;
        else
            _pod = getProperty(null, "pod");
        if (_pod == null || (_pod.startsWith("@") && _pod.endsWith("@"))) {
            _pod = "default";
        }

        if (_host == null || (_host.startsWith("@") && _host.endsWith("@"))) {
            throw new ConfigurationException("Host is not configured correctly: " + _host);
        }

        final String retries = getProperty(null, "ping.retries");
        _pingRetries  = NumbersUtil.parseInt(retries, 5);

        String value = getProperty(null, "developer");
        boolean developer = Boolean.parseBoolean(value);

        if(guid != null)
            _guid = guid;
        else
            _guid = getProperty(null, "guid");
        if (_guid == null) {
            if (!developer) {
                throw new ConfigurationException("Unable to find the guid");
            }
            _guid = MacAddress.getMacAddress().toString(":");
        }

        return true;
    }	

    private void launchAgentFromTypeInfo() throws ConfigurationException {
        String typeInfo = getProperty(null, "type");
        if (typeInfo == null) {
            s_logger.error("Unable to retrieve the type");
            throw new ConfigurationException("Unable to retrieve the type of this agent.");
        }
        s_logger.trace("Launching agent based on type=" + typeInfo);
    }    

    private void launchAgent() throws ConfigurationException {
        String resourceClassNames = getProperty(null, "resource");
        s_logger.trace("resource=" + resourceClassNames);
        if(resourceClassNames != null) {
            launchAgentFromClassInfo(resourceClassNames);
            return;
        }

        launchAgentFromTypeInfo();
    }    

    private void init(String[] args) throws ConfigurationException{

        final Class<?> c = this.getClass();
        _version = c.getPackage().getImplementationVersion();
        if (_version == null) {
            throw new CloudRuntimeException("Unable to find the implementation version of this agent");
        }
        s_logger.info("Implementation Version is " + _version);

        parseCommand(args);

        s_logger.info("Defaulting to using properties file for storage");
        _storage = new PropertiesStorage();
        _storage.configure("Storage", new HashMap<String, Object>());

        // merge with properties from command line to let resource access command line parameters
        for(Map.Entry<String, Object> cmdLineProp : getCmdLineProperties().entrySet()) {
            _properties.put(cmdLineProp.getKey(), cmdLineProp.getValue());
        }

        s_logger.info("Defaulting to the constant time backoff algorithm");
        _backoff = new ConstantTimeBackoff();
        _backoff.configure("ConstantTimeBackoff", new HashMap<String, Object>());
    }	

    private void launchAgentFromClassInfo(String resourceClassNames) throws ConfigurationException {
        String[] names = resourceClassNames.split("\\|");
        for(String name: names) {
            Class<?> impl;
            try {
                impl = Class.forName(name);
                final Constructor<?> constructor = impl.getDeclaredConstructor();
                constructor.setAccessible(true);
                ServerResource resource = (ServerResource)constructor.newInstance();
                launchAgent(getNextAgentId(), resource);
            } catch (final ClassNotFoundException e) {
                throw new ConfigurationException("Resource class not found: " + name);
            } catch (final SecurityException e) {
                throw new ConfigurationException("Security excetion when loading resource: " + name);
            } catch (final NoSuchMethodException e) {
                throw new ConfigurationException("Method not found excetion when loading resource: " + name);
            } catch (final IllegalArgumentException e) {
                throw new ConfigurationException("Illegal argument excetion when loading resource: " + name);
            } catch (final InstantiationException e) {
                throw new ConfigurationException("Instantiation excetion when loading resource: " + name);
            } catch (final IllegalAccessException e) {
                throw new ConfigurationException("Illegal access exception when loading resource: " + name);
            } catch (final InvocationTargetException e) {
                throw new ConfigurationException("Invocation target exception when loading resource: " + name);
            }
        }
    }

    private void launchAgent(int localAgentId, ServerResource resource) throws ConfigurationException {
        // we don't track agent after it is launched for now
        Agent agent = new Agent(this, localAgentId, resource);
        _agents.add(agent);
        agent.start();
    }

    public synchronized int getNextAgentId() {
        return _nextAgentId++;
    }

    private void run(String[] args) {

        try {
            System.setProperty("java.net.preferIPv4Stack","true");			
            loadProperties();
            init(args);

            String instance = getProperty(null, "instance");
            if (instance == null) {
                instance = "";
            } else {
                instance += ".";
            }

            // TODO need to do this check. For Agentshell running on windows needs different approach
            //final String run = "agent." + instance + "pid";
            //s_logger.debug("Checking to see if " + run + "exists.");
            //ProcessUtil.pidCheck(run);	        


            // TODO: For Hyper-V agent.properties need to be revamped to support multiple agents 
            // corresponding to multiple clusters but running on a SCVMM host

            // read the persistent storage and launch the agents
            //launchAgent();

            // FIXME get rid of this approach of agent listening for boot strap commands from the management server

            // now listen for bootstrap request from the management server and launch agents 
            _connection = new NioServer("VmmAgentShell", _listenerPort, 1, this);
            _connection.start();
            s_logger.info("SCVMM agent is listening on port " +_listenerPort + " for bootstrap command from management server");
            while(_connection.isRunning());
        } catch(final ConfigurationException e) {
            s_logger.error("Unable to start agent: " + e.getMessage());
            System.out.println("Unable to start agent: " + e.getMessage());
            System.exit(ExitStatus.Configuration.value());
        } catch (final Exception e) {
            s_logger.error("Unable to start agent: ", e);
            System.out.println("Unable to start agent: " + e.getMessage());
            System.exit(ExitStatus.Error.value());
        }
    }

    @Override
    public Task create(com.cloud.utils.nio.Task.Type type, Link link,
            byte[] data) {
        return new AgentBootStrapHandler(type, link, data);
    } 

    public void stop() {
        _exit = true;
        if(_consoleProxyMain != null) {
            _consoleProxyMain.interrupt();
        }
    }	

    public static void main(String[] args) {

        VmmAgentShell shell = new VmmAgentShell();
        Runtime.getRuntime().addShutdownHook(new ShutdownThread(shell));		
        shell.run(args);
    }   

    // class to handle the bootstrap command from the management server
    private class AgentBootStrapHandler extends Task {

        public AgentBootStrapHandler(Task.Type type, Link link, byte[] data) {
            super(type, link, data);
        }

        @Override
        protected void doTask(Task task) throws Exception {
            final Type type = task.getType();
            s_logger.info("recieved task of type "+ type.toString() +" to handle in BootStrapTakHandler");
            if (type == Task.Type.DATA)
            {
                final byte[] data = task.getData();
                final Request request = Request.parse(data);
                final Command cmd = request.getCommand();

                if (cmd instanceof StartupVMMAgentCommand) {

                    StartupVMMAgentCommand vmmCmd = (StartupVMMAgentCommand) cmd;

                    _zone = Long.toString(vmmCmd.getDataCenter());
                    _cmdLineProperties.put("zone", _zone);

                    _pod = Long.toString(vmmCmd.getPod());
                    _cmdLineProperties.put("pod", _pod);

                    _cluster = vmmCmd.getClusterName();
                    _cmdLineProperties.put("cluster", _cluster);

                    _guid = vmmCmd.getGuid();
                    _cmdLineProperties.put("guid", _guid);

                    _host = vmmCmd.getManagementServerIP();
                    _port =  NumbersUtil.parseInt(vmmCmd.getport(), 8250);

                    s_logger.info("Recieved boot strap command from management server with parameters " +
                            " Zone:"+  _zone + " "+
                            " Cluster:"+ _cluster + " "+
                            " pod:"+_pod + " "+
                            " host:"+ _host +" "+
                            " port:"+_port);

                    launchAgentFromClassInfo("com.cloud.hypervisor.hyperv.resource.HypervResource");

                    // TODO: persist the info in agent.properties for agent restarts
                }
            }
        }
    }

    private static class ShutdownThread extends Thread {
        VmmAgentShell _shell;
        public ShutdownThread(VmmAgentShell shell) {
            this._shell = shell;
        }

        @Override
        public void run() {
            _shell.stop();
        }
    }	

}