/**
 * JaDOrT: JASMINe Deployment Orchestration Tool
 * Copyright (C) 2008-2009 Bull S.A.S.
 * Copyright (C) 2008-2009 France Telecom R&D
 * Contact: jasmine@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: JadortCommand.java 6152 2010-03-12 15:38:16Z alitokmen $
 * --------------------------------------------------------------------------
 */
package org.ow2.jasmine.jadort.client.console;

import java.io.File;
import java.net.URL;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.ow2.jasmine.jadort.api.IJadortService;
import org.ow2.jasmine.jadort.api.entities.deployment.ApplicationBean;
import org.ow2.jasmine.jadort.api.entities.deployment.OperationStateBean;
import org.ow2.jasmine.jadort.api.entities.deployment.ServerProgressBean;
import org.ow2.jasmine.jadort.api.entities.deployment.VMImageBean;
import org.ow2.jasmine.jadort.api.entities.deployment.WorkerProgressBean;
import org.ow2.jasmine.jadort.api.entities.deployment.OperationStateBean.Step;
import org.ow2.jasmine.jadort.api.entities.topology.GroupBean;
import org.ow2.jasmine.jadort.api.entities.topology.ServerBean;
import org.ow2.jasmine.jadort.api.entities.topology.WorkerBean;

/**
 * Interface to call method on JaDOrT service
 * 
 * @author Malek Chahine
 * @author Remy Bresson
 * @author S. Ali Tokmen
 */
public class JadortCommand {

    private IJadortService jadortService;

    /**
     * Constructor
     * 
     * @param JaDOrT The instance of interface of JaDOrT service
     */
    public JadortCommand(final IJadortService jadortService) {
        this.jadortService = jadortService;
    }

    /**
     * Create a new operation and return it
     * 
     * @param newOperationName Name of the operation to create
     * @return The created operation
     * @throws Exception
     */
    public OperationStateBean createNewOperation(final String newOperationName) throws Exception {
        this.jadortService.createNewOperation(newOperationName);
        return this.jadortService.getCurrentOperation();

    }

    /**
     * Return the operation list
     * 
     * @return The operation list
     * @throws Exception
     */
    public List<OperationStateBean> getOperationsList() throws Exception {
        return this.jadortService.getOperationsList();
    }

    /**
     * Select an operation on the JaDOrT service
     * 
     * @param operation The operation to select
     * @throws Exception
     */
    public void selectOperation(final OperationStateBean operation) throws Exception {
        this.jadortService.selectOperation(operation);
    }

    /**
     * Delete an operation
     * 
     * @param operation the operation to delete
     * @throws Exception
     */
    public void deleteOperation(final OperationStateBean operation) throws Exception {
        this.jadortService.deleteOperation(operation);
    }

    /**
     * Load a topology file
     * 
     * @param xmlTopoFile xml topology file to load
     * @throws Exception
     */
    public void loadTopology(final File xmlTopoFile) throws Exception {
        final String xml = FileUtils.readFileToString(xmlTopoFile);
        this.jadortService.loadTopology(xml);
        this.jadortService.next();
    }

    /**
     * Get the groups
     * 
     * @return the groups list
     * @throws Exception
     */
    public List<GroupBean> getGroups() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null && currentOperation.getTopology() != null) {
            return currentOperation.getTopology().getGroups();
        } else {
            return null;
        }
    }

    /**
     * Select a group
     * 
     * @param selectedGroup the group to select
     * @throws Exception
     */
    public void selectGroup(final GroupBean selectedGroup) throws Exception {
        this.jadortService.selectGroup(selectedGroup);
        this.jadortService.next();

    }

    /**
     * Select an operation type on the JaDOrT service
     * 
     * @param operationType The operation type
     * @throws Exception
     */
    public void selectOperationType(final IJadortService.OperationType operationType) throws Exception {
        this.jadortService.selectOperationType(operationType);
        this.jadortService.next();
    }

    /**
     * Select a VM Image
     * 
     * @param vmImage the VM Image to select
     * @throws Exception
     */
    public void selectVMImage(final VMImageBean vmImage) throws Exception {
        this.jadortService.selectVMImage(vmImage);
        this.jadortService.next();

    }

    /**
     * Select a VM Image from the VM Images list for a given server.
     * 
     * @param selectedVMImage the VM Image to be selected
     * @param server the server on which this image shall be deployed
     * @throws Exception
     */
    public void selectVMImage(final VMImageBean vmImage, final ServerBean server) throws Exception {
        this.jadortService.selectVMImage(vmImage, server);
        this.jadortService.next();

    }

    /**
     * get VM Image List
     * 
     * @throws Exception
     */
    public List<VMImageBean> getVMImages() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null && currentOperation.getSelectedGroup() != null) {
            return currentOperation.getSelectedGroup().getVmImages();
        } else {
            return null;
        }
    }

    /**
     * Select servers
     * 
     * @param selectServers the servers list to select
     * @throws Exception
     */
    public void selectServers(final List<ServerBean> selectedServers) throws Exception {
        this.jadortService.selectServers(selectedServers);
        this.jadortService.next();

    }

    /**
     * Return the selected group
     * 
     * @return the selected group
     * @throws Exception
     */
    public GroupBean getSelectedGroup() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null) {
            return currentOperation.getSelectedGroup();
        } else {
            return null;
        }
    }

    /**
     * @return The number of active sessions on all servers:
     *         <ul>
     *         <li>If migrating, it corresponds to the number of active sessions
     *         on the old version. If no old version, this is set to 0.</li>
     *         <li>If maintaining, it corresponds to the number of active
     *         sessions on all applications on the server.</li>
     *         </ul>
     *         This value is re-set every time the object is refreshed on the
     *         stateful bean, and not persisted.
     * @throws Exception
     */
    public Integer getActiveSessions() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null && currentOperation.getSelectedGroup() != null) {
            int sessions = 0;
            for (ServerBean server : currentOperation.getSelectedGroup().getServers()) {
                sessions += server.getActiveSessions();
            }
            return sessions;
        } else {
            return 0;
        }
    }

    /**
     * Create a application from an archive
     * 
     * @param url url of the archive
     * @return the created application
     * @throws Exception
     */
    public ApplicationBean selectApplication(final URL url) throws Exception {
        this.jadortService.selectApplication(url);
        this.jadortService.next();

        return this.jadortService.getCurrentOperation().getApplication();
    }

    /**
     * Return the current operation step
     * 
     * @return the current operation step
     * @throws Exception
     */
    public Step getCurrentStep() throws Exception {
        return this.jadortService.getCurrentStep();
    }

    /**
     * ask the service if it is ready to go to the next step
     * 
     * @return true or false
     * @throws Exception
     */
    public boolean canGoToNextStep() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null) {
            return currentOperation.getCanGoToNextStep();
        } else {
            return false;
        }
    }

    /**
     * Go to the next step
     * 
     * @throws Exception
     */
    public void next() throws Exception {
        this.jadortService.next();
    }

    /**
     * ask the service if it is ready to go to the previous step
     * 
     * @return true or false
     * @throws Exception
     */
    public boolean canGoToPreviousStep() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null) {
            return currentOperation.getCanGoToPreviousStep();
        } else {
            return false;
        }
    }

    /**
     * Go to the previous step
     * 
     * @throws Exception
     */
    public void previous() throws Exception {
        this.jadortService.previous();
    }

    /**
     * Return the list of the serverProgressList
     * 
     * @return the list of the serverProgressList
     * @throws Exception
     */
    public List<ServerProgressBean> getServerProgressList() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null) {
            return currentOperation.getServerProgressList();
        } else {
            return null;
        }
    }

    /**
     * Return the list of the workerProgress
     * 
     * @return the list of the workerProgress
     * @throws Exception
     */
    public List<WorkerProgressBean> getWorkerProgressList() throws Exception {
        OperationStateBean currentOperation = this.jadortService.getCurrentOperation();
        if (currentOperation != null) {
            return currentOperation.getWorkerProgressList();
        } else {
            return null;
        }
    }

    /**
     * Restart the last tried deployment operation on a server. To use when the
     * last operation failed.
     * 
     * @param server the server to use
     * @throws Exception
     */
    public void restartServer(final ServerBean server) throws Exception {
        this.jadortService.restartServer(server);
    }

    /**
     * Ignore the error state of a server. To use when server on error and after
     * user correct himself the error.
     * 
     * @param server the server to use
     * @throws Exception
     */
    public void ignoreServer(final ServerBean server) throws Exception {
        this.jadortService.ignoreServer(server);
    }

    /**
     * Check if the server is ready to go to the next step.
     * 
     * @param server the server to use
     * @return true or false
     * @throws Exception
     */
    public boolean checkServer(final ServerBean server) throws Exception {
        return this.jadortService.checkServer(server);
    }

    /**
     * Restart the last tried worker task on a worker. To use when the last
     * operation failed.
     * 
     * @param worker the worker to use
     * @throws Exception
     */
    public void restartWorker(final WorkerBean worker) throws Exception {
        this.jadortService.restartWorker(worker);
    }

    /**
     * Ignore the error state of a worker. To use when worker on error and after
     * user correct himself the error.
     * 
     * @param worker the worker to use
     * @throws Exception
     */
    public void ignoreWorker(final WorkerBean worker) throws Exception {
        this.jadortService.ignoreWorker(worker);
    }

    /**
     * Check if the worker is ready to go to the next step.
     * 
     * @param worker the worker to use
     * @return true or false
     * @throws Exception
     */
    public boolean checkWorker(final WorkerBean worker) throws Exception {
        return this.jadortService.checkWorker(worker);
    }

}
