/*
 * 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 org.apache.brooklyn.entity.chef;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.collections.Jsonya.Navigator;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskTags;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.ssh.BashCommands;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
import org.apache.brooklyn.util.time.Time;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;

/** 
 * Creates effectors to start, restart, and stop processes using Chef.
 * <p>
 * Instances of this should use the {@link ChefConfig} config attributes to configure startup,
 * and invoke {@link #usePidFile(String)} or {@link #useService(String)} to determine check-running and stop behaviour.
 * Alternatively this can be subclassed and {@link #postStartCustom()} and {@link #stopProcessesAtMachine()} overridden.
 * 
 * @since 0.6.0
 **/
@Beta
public class ChefLifecycleEffectorTasks extends MachineLifecycleEffectorTasks implements ChefConfig {

    private static final Logger log = LoggerFactory.getLogger(ChefLifecycleEffectorTasks.class);
    
    protected String _pidFile, _serviceName, _windowsServiceName;
    
    public ChefLifecycleEffectorTasks() {
    }
    
    public ChefLifecycleEffectorTasks usePidFile(String pidFile) {
        this._pidFile = pidFile;
        return this;
    }
    public ChefLifecycleEffectorTasks useService(String serviceName) {
        this._serviceName = serviceName;
        return this;
    }
    public ChefLifecycleEffectorTasks useWindowsService(String serviceName) {
        this._windowsServiceName = serviceName;
        return this;
    }
    
    public String getPidFile() {
        if (_pidFile!=null) return _pidFile;
        return _pidFile = entity().getConfig(ChefConfig.PID_FILE);
    }

    public String getServiceName() {
        if (_serviceName!=null) return _serviceName;
        return _serviceName = entity().getConfig(ChefConfig.SERVICE_NAME);
    }

    protected String getNodeName() {
        // (node name is needed so we can node delete it)
        
        // TODO would be better if CHEF_NODE_NAME were a freemarker template, could access entity.id, or hostname, etc,
        // in addition to supporting hard-coded node names (which is all we support so far).
        
        String nodeName = entity().getConfig(ChefConfig.CHEF_NODE_NAME);
        if (Strings.isNonBlank(nodeName)) return Strings.makeValidFilename(nodeName);
        // node name is taken from ID of this entity, if not specified
        return entity().getId();
    }

    public String getWindowsServiceName() {
        if (_windowsServiceName!=null) return _windowsServiceName;
        return _windowsServiceName = entity().getConfig(ChefConfig.WINDOWS_SERVICE_NAME);
    }

    @Override
    public void attachLifecycleEffectors(Entity entity) {
        if (getPidFile()==null && getServiceName()==null && getClass().equals(ChefLifecycleEffectorTasks.class)) {
            // warn on incorrect usage
            log.warn("Uses of "+getClass()+" must define a PID file or a service name (or subclass and override {start,stop} methods as per javadoc) " +
                    "in order for check-running and stop to work");
        }
            
        super.attachLifecycleEffectors(entity);
    }

    public static ChefModes detectChefMode(Entity entity) {
        ChefModes mode = entity.getConfig(ChefConfig.CHEF_MODE);
        if (mode == ChefModes.AUTODETECT) {
            // TODO server via API
            ProcessTaskWrapper<Boolean> installCheck = DynamicTasks.queue(
                    ChefServerTasks.isKnifeInstalled());
            mode = installCheck.get() ? ChefModes.KNIFE : ChefModes.SOLO;
            log.debug("Using Chef in "+mode+" mode due to autodetect exit code "+installCheck.getExitCode());
        }
        Preconditions.checkNotNull(mode, "Non-null "+ChefConfig.CHEF_MODE+" required for "+entity);
        return mode;
    }
    
    @Override
    protected String startProcessesAtMachine(Supplier<MachineLocation> machineS) {
        ChefModes mode = detectChefMode(entity());
        switch (mode) {
        case KNIFE:
            startWithKnifeAsync();
            break;
            
        case SOLO:
            startWithChefSoloAsync();
            break;
            
        default:
            throw new IllegalStateException("Unknown Chef mode "+mode+" when starting processes for "+entity());
        }
        
        return "chef start tasks submitted ("+mode+")";
    }

    protected String getPrimaryCookbook() {
        return entity().getConfig(CHEF_COOKBOOK_PRIMARY_NAME);
    }
    
    @SuppressWarnings({ "unchecked", "deprecation" })
    protected void startWithChefSoloAsync() {
        String baseDir = MachineLifecycleEffectorTasks.resolveOnBoxDir(entity(), Machines.findUniqueMachineLocation(entity().getLocations(), SshMachineLocation.class).get());
        String installDir = Urls.mergePaths(baseDir, "installs/chef");
        
        @SuppressWarnings("rawtypes")
        Map<String, String> cookbooks = (Map) 
            ConfigBag.newInstance( entity().getConfig(CHEF_COOKBOOK_URLS) )
            .putIfAbsent( entity().getConfig(CHEF_COOKBOOK_URLS) )
            .getAllConfig();
        if (cookbooks.isEmpty())
            log.warn("No cookbook_urls set for "+entity()+"; launch will likely fail subsequently");
        DynamicTasks.queue(
                ChefSoloTasks.installChef(installDir, false), 
                ChefSoloTasks.installCookbooks(installDir, cookbooks, false));

        // TODO chef for and run a prestart recipe if necessary
        // TODO open ports

        String primary = getPrimaryCookbook();
        
        // put all config under brooklyn/cookbook/config
        Navigator<MutableMap<Object, Object>> attrs = Jsonya.newInstancePrimitive().at("brooklyn");
        if (Strings.isNonBlank(primary)) attrs.at(primary);
        attrs.at("config");
        attrs.put( entity().config().getBag().getAllConfig() );
        // and put launch attrs at root
        try {
            attrs.root().put((Map<?,?>)Tasks.resolveDeepValue(entity().getConfig(CHEF_LAUNCH_ATTRIBUTES), Object.class, entity().getExecutionContext()));
        } catch (Exception e) { Exceptions.propagate(e); }
        
        Collection<? extends String> runList = entity().getConfig(CHEF_LAUNCH_RUN_LIST);
        if (runList==null) runList = entity().getConfig(CHEF_RUN_LIST);
        if (runList==null) {
            if (Strings.isNonBlank(primary)) runList = ImmutableList.of(primary+"::"+"start");
            else throw new IllegalStateException("Require a primary cookbook or a run_list to effect "+"start"+" on "+entity());
        }
        
        String runDir = Urls.mergePaths(baseDir,  
            "apps/"+entity().getApplicationId()+"/chef/entities/"+entity().getEntityType().getSimpleName()+"_"+entity().getId());
        
        DynamicTasks.queue(ChefSoloTasks.buildChefFile(runDir, installDir, "launch", 
                runList, (Map<String, Object>) attrs.root().get()));
        
        DynamicTasks.queue(ChefSoloTasks.runChef(runDir, "launch", entity().getConfig(CHEF_RUN_CONVERGE_TWICE)));
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes", "deprecation" })
    protected void startWithKnifeAsync() {
        // TODO prestart, ports (as above); also, note, some aspects of this are untested as we need a chef server
        
        String primary = getPrimaryCookbook();

        // put all config under brooklyn/cookbook/config
        Navigator<MutableMap<Object, Object>> attrs = Jsonya.newInstancePrimitive().at("brooklyn");
        if (Strings.isNonBlank(primary)) attrs.at(primary);
        attrs.at("config");
        attrs.put( entity().config().getBag().getAllConfig() );
        // and put launch attrs at root
        try {
            attrs.root().put((Map<?,?>)Tasks.resolveDeepValue(entity().getConfig(CHEF_LAUNCH_ATTRIBUTES), Object.class, entity().getExecutionContext()));
        } catch (Exception e) { Exceptions.propagate(e); }

        Collection<? extends String> runList = entity().getConfig(CHEF_LAUNCH_RUN_LIST);
        if (runList==null) runList = entity().getConfig(CHEF_RUN_LIST);
        if (runList==null) {
            if (Strings.isNonBlank(primary)) runList = ImmutableList.of(primary+"::"+"start");
            else throw new IllegalStateException("Require a primary cookbook or a run_list to effect "+"start"+" on "+entity());
        }

        DynamicTasks.queue(
                ChefServerTasks.knifeConvergeTask()
                    .knifeNodeName(getNodeName())
                    .knifeRunList(Strings.join(runList, ","))
                    .knifeAddAttributes((Map) attrs.root().get())
                    .knifeRunTwice(entity().getConfig(CHEF_RUN_CONVERGE_TWICE)) );
    }

    @Override
    protected void postStartCustom() {
        boolean result = false;
        result |= tryCheckStartPid();
        result |= tryCheckStartService();
        result |= tryCheckStartWindowsService();
        if (!result) {
            log.warn("No way to check whether "+entity()+" is running; assuming yes");
        }
        entity().sensors().set(SoftwareProcess.SERVICE_UP, true);
        super.postStartCustom();
    }
    
    protected boolean tryCheckStartPid() {
        if (getPidFile()==null) return false;
        
        // if it's still up after 5s assume we are good (default behaviour)
        Time.sleep(Duration.FIVE_SECONDS);
        if (!DynamicTasks.queue(SshEffectorTasks.isPidFromFileRunning(getPidFile()).runAsRoot()).get()) {
            throw new IllegalStateException("The process for "+entity()+" appears not to be running (pid file "+getPidFile()+")");
        }

        // and set the PID
        entity().sensors().set(Attributes.PID, 
                Integer.parseInt(DynamicTasks.queue(SshEffectorTasks.ssh("cat "+getPidFile()).runAsRoot()).block().getStdout().trim()));
        return true;
    }

    protected boolean tryCheckStartService() {
        if (getServiceName()==null) return false;
        
        // if it's still up after 5s assume we are good (default behaviour)
        Time.sleep(Duration.FIVE_SECONDS);
        if (!((Integer)0).equals(DynamicTasks.queue(SshEffectorTasks.ssh("/etc/init.d/"+getServiceName()+" status").runAsRoot()).get())) {
            throw new IllegalStateException("The process for "+entity()+" appears not to be running (service "+getServiceName()+")");
        }

        return true;
    }

    protected boolean tryCheckStartWindowsService() {
        if (getWindowsServiceName()==null) return false;
        
        // if it's still up after 5s assume we are good (default behaviour)
        Time.sleep(Duration.FIVE_SECONDS);
        if (!((Integer)0).equals(DynamicTasks.queue(SshEffectorTasks.ssh("sc query \""+getWindowsServiceName()+"\" | find \"RUNNING\"").runAsCommand()).get())) {
            throw new IllegalStateException("The process for "+entity()+" appears not to be running (windowsService "+getWindowsServiceName()+")");
        }

        return true;
    }

    @Override
    protected String stopProcessesAtMachine() {
        boolean result = false;
        result |= tryStopService();
        result |= tryStopWindowsService();
        result |= tryStopPid();
        if (!result) {
            throw new IllegalStateException("The process for "+entity()+" could not be stopped (no impl!)");
        }
        return "stopped";
    }
    
    @Override
    protected StopMachineDetails<Integer> stopAnyProvisionedMachines() {
        if (detectChefMode(entity())==ChefModes.KNIFE) {
            DynamicTasks.queue(
                // if this task fails show it as failed but don't block subsequent routines
                // (ie allow us to actually decommission the machine)
                // TODO args could be a List<String> config key ?
                TaskTags.markInessential(
                new KnifeTaskFactory<String>("delete node and client registration at chef server")
                    .add("knife node delete "+getNodeName()+" -y")
                    .add("knife client delete "+getNodeName()+" -y")
                    .requiringZeroAndReturningStdout()
                    .newTask() ));
        }

        return super.stopAnyProvisionedMachines();
    }
    
    protected boolean tryStopService() {
        if (getServiceName()==null) return false;
        int result = DynamicTasks.queue(SshEffectorTasks.ssh("/etc/init.d/"+getServiceName()+" stop").runAsRoot()).get();
        if (0==result) return true;
        if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)!=Lifecycle.RUNNING)
            return true;
        
        throw new IllegalStateException("The process for "+entity()+" appears could not be stopped (exit code "+result+" to service stop)");
    }

    protected boolean tryStopWindowsService() {
        if (getWindowsServiceName()==null) return false;
                int result = DynamicTasks.queue(SshEffectorTasks.ssh("sc query \""+getWindowsServiceName()+"\"").runAsCommand()).get();
        if (0==result) return true;
        if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)!=Lifecycle.RUNNING)
            return true;

        throw new IllegalStateException("The process for "+entity()+" appears could not be stopped (exit code "+result+" to service stop)");
    }

    protected boolean tryStopPid() {
        Integer pid = entity().getAttribute(Attributes.PID);
        if (pid==null) {
            if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)==Lifecycle.RUNNING && getPidFile()==null)
                log.warn("No PID recorded for "+entity()+" when running, with PID file "+getPidFile()+"; skipping kill in "+Tasks.current());
            else 
                if (log.isDebugEnabled())
                    log.debug("No PID recorded for "+entity()+"; skipping ("+entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)+" / "+getPidFile()+")");
            return false;
        }
        
        // allow non-zero exit as process may have already been killed
        DynamicTasks.queue(SshEffectorTasks.ssh(
                "kill "+pid, "sleep 5", BashCommands.ok("kill -9 "+pid)).allowingNonZeroExitCode().runAsRoot()).block();
        
        if (DynamicTasks.queue(SshEffectorTasks.isPidRunning(pid).runAsRoot()).get()) {
            throw new IllegalStateException("Process for "+entity()+" in "+pid+" still running after kill");
        }
        entity().sensors().set(Attributes.PID, null);
        return true;
    }

}
