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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

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

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;

import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.maint.dao.AgentUpgradeDao;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.component.ComponentLocator;

/**
 *
 *  UpgradeManagerImpl implements the upgrade process.  It's functionalities
 *  include
 *    1. Identifying agents that require an upgrade before it can connect.
 *    2. Spread out a release update to agents so that the entire system
 *       does not come down at the same time.
 */
@Local(UpgradeManager.class)
public class UpgradeManagerImpl implements UpgradeManager {
	private final static Logger s_logger = Logger.getLogger(UpgradeManagerImpl.class);

    String _name;
    String _minimalVersion;
    String _recommendedVersion;
//    String _upgradeUrl;
    String _agentPath;
    long _checkInterval;
    
    AgentUpgradeDao _upgradeDao;
    
    @Override
    public State registerForUpgrade(long hostId, String version) {
        State state = State.UpToDate;
        s_logger.debug("Minimal version is " + _minimalVersion + "; version is " + version + "; recommended version is " + _recommendedVersion);
        if (Version.compare(version, _minimalVersion) < 0) {
            state = State.RequiresUpdate;
        } else if (Version.compare(version, _recommendedVersion) < 0) {
            state = State.WaitingForUpdate;
        } else {
            state = State.UpToDate;
        }

        /*
        if (state != State.UpToDate) {
            AgentUpgradeVO vo = _upgradeDao.findById(hostId);
            if (vo == null) {
                vo = new AgentUpgradeVO(hostId, version, state);
                _upgradeDao.persist(vo);
            }
        }
        */
        
        return state;
    }
    
    public String deployNewAgent(String url) {
        s_logger.info("Updating agent with binary from " + url);

        final HttpClient client = new HttpClient();
        final GetMethod method = new GetMethod(url);
        int response;
        File file = null;
        try {
            response = client.executeMethod(method);
            if (response != HttpURLConnection.HTTP_OK) {
                s_logger.warn("Retrieving the agent gives response code: " + response);
                return "Retrieving the file from " + url + " got response code: " + response;
            }

            final InputStream is = method.getResponseBodyAsStream();
            file = File.createTempFile("agent-", "-" + Long.toString(new Date().getTime()));
            file.deleteOnExit();

            s_logger.debug("Retrieving new agent into " + file.getAbsolutePath());

            final FileOutputStream fos = new FileOutputStream(file);

            final ByteBuffer buffer = ByteBuffer.allocate(2048);
            final ReadableByteChannel in = Channels.newChannel(is);
            final WritableByteChannel out = fos.getChannel();

            while (in.read(buffer) != -1) {
                buffer.flip();
                out.write(buffer);
                buffer.clear();
            }

            in.close();
            out.close();

            s_logger.debug("New Agent zip file is now retrieved");
        } catch (final HttpException e) {
        	return "Unable to retrieve the file from " + url;
        } catch (final IOException e) {
        	return "Unable to retrieve the file from " + url;
        }
        
        file.delete();
        
        return "File will be deployed.";
    }
    
//    @Override
//    public String getAgentUrl() {
//        return _upgradeUrl;
//    }

    @Override
    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
        _name = name;

        final ComponentLocator locator = ComponentLocator.getCurrentLocator();
        _upgradeDao = locator.getDao(AgentUpgradeDao.class);
        if (_upgradeDao == null) {
            throw new ConfigurationException("Unable to retrieve the storage layer.");
        }

        ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
        if (configDao == null) {
            throw new ConfigurationException("Unable to get the configuration dao.");
        }

        final Map<String, String> configs = configDao.getConfiguration("UpgradeManager", params);

        File agentUpgradeFile = PropertiesUtil.findConfigFile("agent-update.properties");
        Properties agentUpgradeProps = new Properties();
        try {
            if (agentUpgradeFile != null) {
                agentUpgradeProps.load(new FileInputStream(agentUpgradeFile));
            }

            _minimalVersion = agentUpgradeProps.getProperty("agent.minimal.version");
            _recommendedVersion = agentUpgradeProps.getProperty("agent.recommended.version");

            if (_minimalVersion == null) {
                _minimalVersion = "0.0.0.0";
            }

            if (_recommendedVersion == null) {
                _recommendedVersion = _minimalVersion;
            }

            //_upgradeUrl = configs.get("upgrade.url");
            
//			if (_upgradeUrl == null) {
//				s_logger.debug("There is no upgrade url found in configuration table");
//                // _upgradeUrl = "http://updates.vmops.com/releases/rss.xml";
//            }

            return true;
        } catch (IOException ex) {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Error reading agent-update.properties:  " + ex);
            }
        }
        return false;
    }

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

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

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