/*
 * 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.brooklynnode;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.drivers.downloads.DownloadSubstituters;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.file.ArchiveBuilder;
import org.apache.brooklyn.util.core.file.ArchiveUtils;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.ssh.BashCommands;
import org.apache.brooklyn.util.text.Identifiers;
import org.apache.brooklyn.util.text.Strings;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

public class BrooklynNodeSshDriver extends JavaSoftwareProcessSshDriver implements BrooklynNodeDriver {
    
    public BrooklynNodeSshDriver(BrooklynNodeImpl entity, SshMachineLocation machine) {
        super(entity, machine);
    }

    @Override
    public BrooklynNodeImpl getEntity() {
        return (BrooklynNodeImpl) super.getEntity();
    }

    public String getBrooklynHome() {
        return getRunDir();
    }

    @Override
    protected String getLogFileLocation() {
        return Os.mergePathsUnix(getRunDir(), "console");
    }
    
    protected String getPidFile() {
        return Os.mergePathsUnix(getRunDir(), "pid_java");
    }
    
    @Override
    protected String getInstallLabelExtraSalt() {
        String downloadUrl = entity.getConfig(BrooklynNode.DOWNLOAD_URL);
        String uploadUrl = entity.getConfig(BrooklynNode.DISTRO_UPLOAD_URL);
        if (Objects.equal(downloadUrl, BrooklynNode.DOWNLOAD_URL.getConfigKey().getDefaultValue()) &&
                Objects.equal(uploadUrl, BrooklynNode.DISTRO_UPLOAD_URL.getDefaultValue())) {
            // if both are at the default value, then no salt
            return null;
        }
        return Identifiers.makeIdFromHash(Objects.hashCode(downloadUrl, uploadUrl));
    }

    @Override
    public void preInstall() {
        resolver = Entities.newDownloader(this);
        String subpath = entity.getConfig(BrooklynNode.SUBPATH_IN_ARCHIVE);
        if (subpath==null) {
            // assume the dir name is `basename-VERSION` where download link is `basename-VERSION-dist.tar.gz`
            String uploadUrl = entity.getConfig(BrooklynNode.DISTRO_UPLOAD_URL);
            String origDownloadName = uploadUrl;
            if (origDownloadName==null) 
                origDownloadName = entity.getAttribute(BrooklynNode.DOWNLOAD_URL);
            if (origDownloadName!=null) {
                // BasicDownloadResolver makes it crazy hard to get the template-evaluated value of DOWNLOAD_URL
                origDownloadName = DownloadSubstituters.substitute(origDownloadName, DownloadSubstituters.getBasicEntitySubstitutions(this));
                origDownloadName = Urls.decode(origDownloadName);
                origDownloadName = Urls.getBasename(origDownloadName);
                String downloadName = origDownloadName;
                downloadName = Strings.removeFromEnd(downloadName, ".tar.gz");
                downloadName = Strings.removeFromEnd(downloadName, ".tgz");
                downloadName = Strings.removeFromEnd(downloadName, ".zip");
                if (!downloadName.equals(origDownloadName)) {
                    downloadName = Strings.removeFromEnd(downloadName, "-dist");
                    subpath = downloadName;
                }
            }
        }
        if (subpath==null) subpath = format("brooklyn-dist-%s", getVersion());
        setExpandedInstallDir(Os.mergePaths(getInstallDir(), resolver.getUnpackedDirectoryName(subpath)));
    }

    @Override
    public void clearInstallDir() {
        super.setInstallDir(null);
        super.setExpandedInstallDir(null);
    }
    
    @Override
    public void install() {
        String uploadUrl = entity.getConfig(BrooklynNode.DISTRO_UPLOAD_URL);
        
        // Need to explicitly give file, because for snapshot URLs you don't get a clean filename from the URL.
        // This filename is used to generate the first URL to try: [BROOKLYN_VERSION_BELOW]
        // file://$HOME/.brooklyn/repository/BrooklynNode/0.8.1-SNAPSHOT/brooklynnode-0.8.0-snapshot.tar.gz
        // (DOWNLOAD_URL overrides this and has a default which comes from maven)
        List<String> urls = resolver.getTargets();
        String saveAs = resolver.getFilename();
        
        newScript("createInstallDir")
                .body.append("mkdir -p "+getInstallDir())
                .failOnNonZeroResultCode()
                .execute();

        List<String> commands = Lists.newArrayList();
        // TODO use machine.installTo ... but that only works w a single location currently
        if (uploadUrl != null) {
            // Only upload if not already installed
            boolean exists = newScript("checkIfInstalled")
                    .body.append("cd "+getInstallDir(), "test -f BROOKLYN")
                    .execute() == 0;
            if (!exists) {
                InputStream distroStream = resource.getResourceFromUrl(uploadUrl);
                getMachine().copyTo(distroStream, getInstallDir()+"/"+saveAs);
            }
        } else {
            commands.addAll(BashCommands.commandsToDownloadUrlsAs(urls, saveAs));
        }
        commands.add(BashCommands.INSTALL_TAR);
        commands.add("tar xzfv " + saveAs);
        
        newScript(INSTALLING).
                failOnNonZeroResultCode().
                body.append(commands).execute();
    }

    @Override
    public void customize() {
        newScript(CUSTOMIZING)
                .failOnNonZeroResultCode()
                .body.append(
                        // workaround for AMP distribution placing everything in the root of this archive, but
                        // brooklyn distribution placing everything in a subdirectory: check to see if subdirectory
                        // with expected name exists; symlink to same directory if it doesn't
                        // FIXME remove when all downstream usages don't use this
                        format("[ -d %1$s ] || ln -s . %1$s", getExpandedInstallDir(), getExpandedInstallDir()),
                        
                        // previously we only copied bin,conf and set BROOKLYN_HOME to the install dir;
                        // but that does not play nicely if installing dists other than brooklyn
                        // (such as what is built by our artifact)  
                        format("cp -R %s/* .", getExpandedInstallDir()),
                        "mkdir -p ./lib/")
                .execute();
        
        SshMachineLocation machine = getMachine();
        BrooklynNode entity = getEntity();
        
        String brooklynGlobalPropertiesRemotePath = entity.getConfig(BrooklynNode.BROOKLYN_GLOBAL_PROPERTIES_REMOTE_PATH);
        String brooklynGlobalPropertiesContents = entity.getConfig(BrooklynNode.BROOKLYN_GLOBAL_PROPERTIES_CONTENTS);
        String brooklynGlobalPropertiesUri = entity.getConfig(BrooklynNode.BROOKLYN_GLOBAL_PROPERTIES_URI);

        String brooklynLocalPropertiesRemotePath = processTemplateContents(entity.getConfig(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_REMOTE_PATH));
        String brooklynLocalPropertiesContents = entity.getConfig(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_CONTENTS);
        String brooklynLocalPropertiesUri = entity.getConfig(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_URI);

        String brooklynCatalogRemotePath = entity.getConfig(BrooklynNode.BROOKLYN_CATALOG_REMOTE_PATH);
        String brooklynCatalogContents = entity.getConfig(BrooklynNode.BROOKLYN_CATALOG_CONTENTS);
        String brooklynCatalogUri = entity.getConfig(BrooklynNode.BROOKLYN_CATALOG_URI);

        // Override the ~/.brooklyn/brooklyn.properties if required
        if (brooklynGlobalPropertiesContents != null || brooklynGlobalPropertiesUri != null) {
            ExistingFileBehaviour onExisting = entity.getConfig(BrooklynNode.ON_EXISTING_PROPERTIES_FILE);
            Integer checkExists = DynamicTasks.queue(SshEffectorTasks.ssh("ls \""+brooklynGlobalPropertiesRemotePath+"\"").allowingNonZeroExitCode()).get();
            boolean doUpload = true;
            if (checkExists==0) {
                switch (onExisting) {
                case USE_EXISTING: doUpload = false; break;
                case OVERWRITE: break;
                case DO_NOT_USE: 
                    throw new IllegalStateException("Properties file "+brooklynGlobalPropertiesContents+" already exists and "+
                        "even though it is not being used, content for it was supplied");
                case FAIL: 
                    throw new IllegalStateException("Properties file "+brooklynGlobalPropertiesContents+" already exists and "+
                        BrooklynNode.ON_EXISTING_PROPERTIES_FILE+" response is to fail");
                default:
                    throw new IllegalStateException("Properties file "+brooklynGlobalPropertiesContents+" already exists and "+
                        BrooklynNode.ON_EXISTING_PROPERTIES_FILE+" response "+onExisting+" is unknown");
                }
            }
            if (onExisting==ExistingFileBehaviour.DO_NOT_USE) {
                log.warn("Global properties supplied when told not to use them; no global properties exists, so it will be installed, but it will not be used.");
            }
            if (doUpload)
                uploadFileContents(brooklynGlobalPropertiesContents, brooklynGlobalPropertiesUri, brooklynGlobalPropertiesRemotePath);
        }
        
        // Upload a local-brooklyn.properties if required
        if (brooklynLocalPropertiesContents != null || brooklynLocalPropertiesUri != null) {
            uploadFileContents(brooklynLocalPropertiesContents, brooklynLocalPropertiesUri, brooklynLocalPropertiesRemotePath);
        }

        // Override the ~/.brooklyn/catalog.xml if required
        if (brooklynCatalogContents != null || brooklynCatalogUri != null) {
            uploadFileContents(brooklynCatalogContents, brooklynCatalogUri, brooklynCatalogRemotePath);
        }

        // Copy additional resources to the server
        for (Map.Entry<String,String> entry : getEntity().getAttribute(BrooklynNode.COPY_TO_RUNDIR).entrySet()) {
            Map<String, String> substitutions = ImmutableMap.of("RUN", getRunDir());
            String localResource = entry.getKey();
            String remotePath = entry.getValue();
            String resolvedRemotePath = remotePath;
            for (Map.Entry<String,String> substitution : substitutions.entrySet()) {
                String key = substitution.getKey();
                String val = substitution.getValue();
                resolvedRemotePath = resolvedRemotePath.replace("${"+key+"}", val).replace("$"+key, val);
            }
            machine.copyTo(MutableMap.of("permissions", "0600"), resource.getResourceFromUrl(localResource), resolvedRemotePath);
        }

        for (String entry : getEntity().getClasspath()) {
            // If a local folder, then create archive from contents first
            if (Urls.isDirectory(entry)) {
                File jarFile = ArchiveBuilder.jar().addDirContentsAt(new File(entry), "").create();
                entry = jarFile.getAbsolutePath();
            }

            // Determine filename
            String destFile = entry.contains("?") ? entry.substring(0, entry.indexOf('?')) : entry;
            destFile = destFile.substring(destFile.lastIndexOf('/') + 1);

            ArchiveUtils.deploy(MutableMap.<String, Object>of(), entry, machine, getRunDir(), Os.mergePaths(getRunDir(), "lib"), destFile);
        }
        
        String cmd = entity.getConfig(BrooklynNode.EXTRA_CUSTOMIZATION_SCRIPT);
        if (Strings.isNonBlank(cmd)) {
            DynamicTasks.queueIfPossible( SshEffectorTasks.ssh(cmd).summary("Bespoke BrooklynNode customization script")
                .requiringExitCodeZero() )
                .orSubmitAndBlock(getEntity());
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    public void launch() {
        String app = getEntity().getAttribute(BrooklynNode.APP);
        String locations = getEntity().getAttribute(BrooklynNode.LOCATIONS);
        boolean hasLocalBrooklynProperties = getEntity().getConfig(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_CONTENTS) != null || getEntity().getConfig(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_URI) != null;
        String localBrooklynPropertiesPath = processTemplateContents(getEntity().getConfig(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_REMOTE_PATH));
        InetAddress bindAddress = getEntity().getAttribute(BrooklynNode.WEB_CONSOLE_BIND_ADDRESS);
        InetAddress publicAddress = getEntity().getAttribute(BrooklynNode.WEB_CONSOLE_PUBLIC_ADDRESS);

        String cmd = entity.getConfig(BrooklynNode.LAUNCH_COMMAND);
        if (Strings.isBlank(cmd)) cmd = "./bin/brooklyn";
        cmd = "nohup " + cmd + " launch";
        if (app != null) {
            cmd += " --app "+app;
        }
        if (locations != null) {
            cmd += " --locations "+locations;
        }
        if (entity.getConfig(BrooklynNode.ON_EXISTING_PROPERTIES_FILE)==ExistingFileBehaviour.DO_NOT_USE) {
            cmd += " --noGlobalBrooklynProperties";
        }
        if (hasLocalBrooklynProperties) {
            cmd += " --localBrooklynProperties "+localBrooklynPropertiesPath;
        }
        Integer webPort = null;
        if (getEntity().isHttpProtocolEnabled("http")) {
            webPort = getEntity().getAttribute(BrooklynNode.HTTP_PORT);
            Networking.checkPortsValid(ImmutableMap.of("webPort", webPort));
        } else if (getEntity().isHttpProtocolEnabled("https")) {
            webPort = getEntity().getAttribute(BrooklynNode.HTTPS_PORT);
            Networking.checkPortsValid(ImmutableMap.of("webPort", webPort));
        }
        if (webPort!=null) {
            cmd += " --port "+webPort;
        } else if (getEntity().getEnabledHttpProtocols().isEmpty()) {
            // TODO sensors will probably not work in this mode
            cmd += " --noConsole";
        } else {
            throw new IllegalStateException("Unknown web protocol in "+BrooklynNode.ENABLED_HTTP_PROTOCOLS+" "
                + "("+getEntity().getEnabledHttpProtocols()+"); expecting 'http' or 'https'");
        }
        
        if (bindAddress != null) {
            cmd += " --bindAddress "+bindAddress.getHostAddress();
        }
        if (publicAddress != null) {
            cmd += " --publicAddress "+publicAddress.getHostName();
        }
        if (getEntity().getAttribute(BrooklynNode.NO_WEB_CONSOLE_AUTHENTICATION)) {
            cmd += " --noConsoleSecurity";
        }
        if (Strings.isNonBlank(getEntity().getConfig(BrooklynNode.EXTRA_LAUNCH_PARAMETERS))) {
            cmd += " "+getEntity().getConfig(BrooklynNode.EXTRA_LAUNCH_PARAMETERS);
        }
        cmd += format(" >> %s/console 2>&1 </dev/null &", getRunDir());
        
        log.info("Starting brooklyn on {} using command {}", getMachine(), cmd);
        
        // relies on brooklyn script creating pid file
        newScript(ImmutableMap.of("usePidFile", 
                entity.getConfig(BrooklynNode.LAUNCH_COMMAND_CREATES_PID_FILE) ? false : getPidFile()), 
            LAUNCHING).
            body.append(
                format("export BROOKLYN_CLASSPATH=%s", getRunDir()+"/lib/\"*\""),
                format("export BROOKLYN_HOME=%s", getBrooklynHome()),
                format(cmd)
        ).failOnNonZeroResultCode().execute();
    }

    @Override
    public boolean isRunning() {
        Map<String,String> flags = ImmutableMap.of("usePidFile", getPidFile());
        int result = newScript(flags, CHECK_RUNNING).execute();
        return result == 0;
    }

    @Override
    public void stop() {
        Map<String,String> flags = ImmutableMap.of("usePidFile", getPidFile());
        newScript(flags, STOPPING).execute();
    }

    @Override
    public void kill() {
        Map<String,String> flags = ImmutableMap.of("usePidFile", getPidFile());
        newScript(flags, KILLING).execute();
    }
    
    @Override
    public Map<String, String> getShellEnvironment() {
        Map<String, String> orig = super.getShellEnvironment();
        String origClasspath = orig.get("CLASSPATH");
        String newClasspath = (origClasspath == null ? "" : origClasspath+":") + 
                getRunDir()+"/conf/" + ":" +
                getRunDir()+"/lib/\"*\"";
        Map<String,String> results = new LinkedHashMap<String,String>();
        results.putAll(orig);
        results.put("BROOKLYN_CLASSPATH", newClasspath);
        results.put("BROOKLYN_HOME", getBrooklynHome());
        results.put("RUN", getRunDir());
        return results;
    }
    
    private void uploadFileContents(String contents, String alternativeUri, String remotePath) {
        checkNotNull(remotePath, "remotePath");
        SshMachineLocation machine = getMachine();
        String tempRemotePath = String.format("%s/upload.tmp", getRunDir());

        if (contents == null && alternativeUri == null) {
            throw new IllegalStateException("No contents supplied for file " + remotePath);
        }
        InputStream stream = contents != null
                ? new ByteArrayInputStream(contents.getBytes())
                : resource.getResourceFromUrl(alternativeUri);
        Map<String, String> flags = MutableMap.of(SshTool.PROP_PERMISSIONS.getName(), "0600");
        machine.copyTo(flags, stream, tempRemotePath);
        newScript(CUSTOMIZING)
                .failOnNonZeroResultCode()
                .body.append(
                        format("mkdir -p %s", remotePath.subSequence(0, remotePath.lastIndexOf("/"))),
                        format("cp -p %s %s", tempRemotePath, remotePath),
                        format("rm -f %s", tempRemotePath))
                .execute();
    }
}
