/*
 * This software is distributed under following license based on modified BSD
 * style license.
 * ----------------------------------------------------------------------
 * 
 * Copyright 2009 The Nimbus2 Project. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE NIMBUS PROJECT ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE NIMBUS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the Nimbus2 Project.
 */
package jp.ossc.nimbus.core;

import java.util.Iterator;
import java.util.Set;
import java.util.LinkedHashSet;

/**
 * サービス制御サービス。<p>
 * サービスをグルーピングして制御するサービスです。<br>
 *
 * @author M.Takata
 */
public class ServiceControlService extends ServiceBase implements ServiceControlServiceMBean{
    
    private static final long serialVersionUID = -6687538751630369946L;
    
    private ServiceName[] serviceNames;
    private Set<Service> services;
    private boolean isUseServiceManager;
    
    public void setUseServiceManager(boolean isUse){
        isUseServiceManager = isUse;
    }
    public boolean isUseServiceManager(){
        return isUseServiceManager;
    }
    
    public void setServiceNames(ServiceName[] names){
        serviceNames = names;
    }
    public ServiceName[] getServiceNames(){
        return serviceNames;
    }
    
    public void addService(Service service){
        services.add(service);
    }
    
    public void removeService(Service service){
        services.remove(service);
    }
    
    public void clearServices(){
        services.clear();
    }
    
    public Set<Service> getServiceSet(){
        return services;
    }
    
    public void createService() throws Exception{
        services = new LinkedHashSet<Service>();
    }
    
    public void destroyService() throws Exception{
        services = null;
    }
    
    public void createServices() throws Exception{
        controlServices(State.CREATING);
    }
    
    public void startServices() throws Exception{
        controlServices(State.STARTING);
    }
    
    public void stopServices() throws Exception{
        controlServices(State.STOPPING);
    }
    
    public void destroyServices() throws Exception{
        controlServices(State.DESTROYING);
    }
    
    public void restartServices() throws Exception{
        controlServices(State.STOPPING);
        controlServices(State.STARTING);
    }
    
    private void controlServices(State state) throws Exception{
        if(serviceNames != null){
            for(int i = 0; i < serviceNames.length; i++){
                if(isUseServiceManager){
                    ServiceManager manager = ServiceManagerFactory.findManager(serviceNames[i].getServiceManagerName());
                    if(manager != null){
                        switch(state){
                        case CREATING:
                            manager.createService(serviceNames[i].getServiceName());
                            break;
                        case STARTING:
                            manager.startService(serviceNames[i].getServiceName());
                            break;
                        case STOPPING:
                            manager.stopService(serviceNames[i].getServiceName());
                            break;
                        case DESTROYING:
                            manager.destroyService(serviceNames[i].getServiceName());
                            break;
                        }
                    }
                }else{
                    switch(state){
                    case CREATING:
                        ServiceManagerFactory.getService(serviceNames[i]).create();
                        break;
                    case STARTING:
                        ServiceManagerFactory.getService(serviceNames[i]).start();
                        break;
                    case STOPPING:
                        ServiceManagerFactory.getService(serviceNames[i]).stop();
                        break;
                    case DESTROYING:
                        ServiceManagerFactory.getService(serviceNames[i]).destroy();
                        break;
                    }
                }
            }
        }
        if(services != null){
            Iterator<Service> itr = services.iterator();
            while(itr.hasNext()){
                Service service = itr.next();
                if(isUseServiceManager){
                    ServiceManager manager = ServiceManagerFactory.findManager(service.getServiceManagerName());
                    if(manager != null){
                        switch(state){
                        case CREATING:
                            manager.createService(service.getServiceName());
                            break;
                        case STARTING:
                            manager.startService(service.getServiceName());
                            break;
                        case STOPPING:
                            manager.stopService(service.getServiceName());
                            break;
                        case DESTROYING:
                            manager.destroyService(service.getServiceName());
                            break;
                        }
                    }
                }else{
                    switch(state){
                    case CREATING:
                        service.create();
                        break;
                    case STARTING:
                        service.start();
                        break;
                    case STOPPING:
                        service.stop();
                        break;
                    case DESTROYING:
                        service.destroy();
                        break;
                    }
                }
            }
        }
    }
}
