/*
 * 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.flex.utilities.converter.core;

import org.apache.commons.cli.*;
import org.apache.commons.io.FileUtils;
import org.apache.flex.utilities.converter.air.AirConverter;
import org.apache.flex.utilities.converter.api.ProxySettings;
import org.apache.flex.utilities.converter.deployer.aether.AetherDeployer;
import org.apache.flex.utilities.converter.flash.FlashConverter;
import org.apache.flex.utilities.converter.flex.FlexConverter;
import org.apache.flex.utilities.converter.fontkit.FontkitConverter;
import org.apache.flex.utilities.converter.retrievers.download.DownloadRetriever;
import org.apache.flex.utilities.converter.retrievers.types.PlatformType;
import org.apache.flex.utilities.converter.retrievers.types.SdkType;
import org.apache.flex.utilities.converter.wrapper.WrapperConverter;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class SdkConverterCLI {

    public static final String COMMAND_HELP = "help";
    public static final String COMMAND_LIST = "list";
    public static final String COMMAND_DOWNLOAD = "download";
    public static final String COMMAND_CONVERT = "convert";
    public static final String COMMAND_DEPLOY = "deploy";

    public static final String OPTION_FLEX_VERSION = "flexVersion";
    public static final String OPTION_FLASH_VERSIONS = "flashVersions";
    public static final String OPTION_AIT_VERSION = "airVersion";
    public static final String OPTION_FONTKIT = "fontkit";
    public static final String OPTION_PLATFORMS = "platforms";

    public static final String OPTION_FDK_DIR = "fdkDir";
    public static final String OPTION_MAVEN_DIR = "mavenDir";

    public static final String OPTION_REPO_URL = "repoUrl";
    public static final String OPTION_REPO_USERNAME = "repoUsername";
    public static final String OPTION_REPO_PASSWORD = "repoPassword";

    public static final String OPTION_PROXY_PROTOCOL = "proxyProtocol";
    public static final String OPTION_PROXY_HOST = "proxyHost";
    public static final String OPTION_PROXY_PORT = "proxyPort";
    public static final String OPTION_PROXY_NON_PROXY_HOST = "proxyNonProxyHost";
    public static final String OPTION_PROXY_USERNAME = "proxyUsername";
    public static final String OPTION_PROXY_PASSWORD = "proxyPassword";


    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {
        Options options = new Options();
        options.addOption(OptionBuilder.withArgName("version").hasArg().
                withDescription("(Optional and Only valid for download) Version of the " +
                        "FDK which should be downloaded.").
                isRequired(false).
                create(OPTION_FLEX_VERSION));
        options.addOption(OptionBuilder.withArgName("version(s)").hasArg().
                withValueSeparator(',').
                withDescription("(Optional and Only valid for download) Version(s) of the " +
                        "Adobe Flash SDK which should be downloaded. Multiple versions can " +
                        "be separated by \",\".").
                isRequired(false).
                create(OPTION_FLASH_VERSIONS));
        options.addOption(OptionBuilder.withArgName("version").hasArg().
                withDescription("(Optional and Only valid for download) Version of the " +
                        "Adobe Air SDK which should be downloaded.").
                isRequired(false).
                create(OPTION_AIT_VERSION));
        options.addOption(OptionBuilder.
                withDescription("(Optional and Only valid for download) If provided, the " +
                        "Converter will also download the Fontkit libraries needed for font " +
                        "encoding.").
                isRequired(false).
                create(OPTION_FONTKIT));
        options.addOption(OptionBuilder.withArgName("platform(s)").hasArg().
                withValueSeparator(',').
                withDescription("(Optional and Only valid for download) Platform the artifacts " +
                        "should be downloaded for. If omitted the platform this process is run " +
                        "on will be used. Valid options are: \"WINDOWS\", \"MAC\" and \"LNX\". " +
                        "Multiple versions can be separated by \",\".").
                isRequired(false).
                create(OPTION_PLATFORMS));
        options.addOption(OptionBuilder.withArgName("dir").hasArg().
                withDescription("(Optional) Directory that the FDK will be located in. " +
                        "If omitted, a temporary directory will be used.").
                isRequired(false).
                create(OPTION_FDK_DIR));
        options.addOption(OptionBuilder.withArgName("dir").hasArg().
                withDescription("(Optional) Directory that the mavenized artifacts will be located in. " +
                        "If omitted, a temporary directory will be used.").
                isRequired(false).
                create(OPTION_MAVEN_DIR));
        options.addOption(OptionBuilder.withArgName("url").hasArg().
                withDescription("(Optional and only valid for deploy) Url of the remote Maven " +
                        "repository that the generated Maven artifacts should be deployed to.").
                isRequired(false).
                create(OPTION_REPO_URL));
        options.addOption(OptionBuilder.withArgName("username").hasArg().
                withDescription("(Optional and only valid for deploy) Username used to authenticate " +
                        "on the remote Maven repository that the generated Maven artifacts should be " +
                        "deployed to.").
                isRequired(false).
                create(OPTION_REPO_USERNAME));
        options.addOption(OptionBuilder.withArgName("password").hasArg().
                withDescription("(Optional and only valid for deploy) Password used to authenticate " +
                        "on the remote Maven repository that the generated Maven artifacts should be " +
                        "deployed to.").
                isRequired(false).
                create(OPTION_REPO_PASSWORD));
        options.addOption(OptionBuilder.withArgName("protocol").hasArg().
                withDescription("(Optional and only valid when providing a proxy host and port) protocol " +
                        "to be used to communicate through a proxy server.").
                isRequired(false).
                create(OPTION_PROXY_PROTOCOL));
        options.addOption(OptionBuilder.withArgName("host").hasArg().
                withDescription("(Optional and only valid when providing a proxy host and port) host name " +
                        "of the proxy server.").
                isRequired(false).
                create(OPTION_PROXY_HOST));
        options.addOption(OptionBuilder.withArgName("port").hasArg().
                withDescription("(Optional and only valid when providing a proxy host and port) port " +
                        "of the proxy server.").
                isRequired(false).
                create(OPTION_PROXY_HOST));
        options.addOption(OptionBuilder.withArgName("non-proxy-host(s)").hasArg().
                withDescription("(Optional and only valid when providing a proxy host and port) list of " +
                        "hosts that should not use the proxy server.").
                isRequired(false).
                create(OPTION_PROXY_NON_PROXY_HOST));
        options.addOption(OptionBuilder.withArgName("username").hasArg().
                withDescription("(Optional and only valid when providing a proxy host and port) username " +
                        "used to authenticate at the proxy server.").
                isRequired(false).
                create(OPTION_PROXY_USERNAME));
        options.addOption(OptionBuilder.withArgName("password").hasArg().
                withDescription("(Optional and only valid when providing a proxy host and port) password " +
                        "used to authenticate at the proxy server.").
                isRequired(false).
                create(OPTION_PROXY_PASSWORD));

        CommandLineParser parser = new BasicParser();
        try {
            CommandLine cmd = parser.parse(options, args);
            if(cmd.getArgList().isEmpty() || cmd.getArgList().contains(COMMAND_HELP)) {
                printHelp(options);
                System.exit(0);
            }

            // Find out the desired platform(s).
            List<PlatformType> platforms = new ArrayList<PlatformType>();
            String platformParam = cmd.getOptionValue(OPTION_PLATFORMS);
            if((platformParam != null) && !platformParam.isEmpty()) {
                String[] platformNames = platformParam.split(",");
                for(String platformName : platformNames) {
                    platforms.add(PlatformType.valueOf(platformName));
                }
            }

            if(platforms.isEmpty()) {
                try {
                    platforms.add(PlatformType.getCurrent());
                } catch (Exception e) {
                    System.err.println("Unsupported OS type. Provide manually using 'platform' parameter.");
                    System.exit(1);
                }
            }

            /////////////////////////////////////////////////////////
            // Validate sensible combinations of commands.
            /////////////////////////////////////////////////////////

            // Check that all commands are valid.
            for(String command : (List<String>) cmd.getArgList()) {
                if(!COMMAND_LIST.equals(command) && !COMMAND_DOWNLOAD.equals(command) &&
                        !COMMAND_CONVERT.equals(command) && !COMMAND_DEPLOY.equals(command)) {
                    System.err.println("Unsupported command '" + command + "'.");
                    System.exit(1);
                }
            }

            // Downloading and deploying without converting doesn't make sense.
            if(cmd.getArgList().contains(COMMAND_DOWNLOAD) && !cmd.getArgList().contains(COMMAND_CONVERT) &&
                    cmd.getArgList().contains(COMMAND_DEPLOY)) {
                System.err.println("Downloading and deploying without conversion doesn't make much sense.");
                System.exit(1);
            }

            // If Downloading and not converting, the fdkDir parameter has to be provided as
            // otherwise the download result would reside in some strange temp directory.
            if(cmd.getArgList().contains(COMMAND_DOWNLOAD) && !cmd.getArgList().contains(COMMAND_CONVERT)
                    && !cmd.hasOption(OPTION_FDK_DIR)) {
                System.err.println("Parameter 'fdkDir' required for task 'download' without conversion.");
                System.exit(1);
            }

            // If Converting and not deploying, the mavenDir parameter has to be provided as
            // otherwise the converted FDK would reside in some strange temp directory.
            if(cmd.getArgList().contains(COMMAND_CONVERT) && !cmd.getArgList().contains(COMMAND_DEPLOY)
                    && !cmd.hasOption(OPTION_MAVEN_DIR)) {
                System.err.println("Parameter 'mavenDir' required for task 'convert' without deployment.");
                System.exit(1);
            }

            // Downloading nothing doesn't really make sense. On the bad side it even causes
            // problems with the converter without any fdkDir parameter, therefore we abort here.
            if(cmd.getArgList().contains(COMMAND_DOWNLOAD) && !cmd.hasOption(OPTION_FLEX_VERSION) &&
                    !cmd.hasOption(OPTION_FLASH_VERSIONS) && !cmd.hasOption(OPTION_AIT_VERSION) &&
                    !cmd.hasOption(OPTION_FONTKIT)) {
                System.err.println("At least one of the parameters 'flexVersion', 'flashVersions', 'airVersion' or " +
                        "'fontkit' required for task 'download'.");
                System.exit(1);
            }

            // Find out where to download or convert from.
            File fdkDir = cmd.hasOption(OPTION_FDK_DIR) ?
                    new File(cmd.getOptionValue(OPTION_FDK_DIR)) : getTempDir("FLEX-DOWNLOAD-");

            // Find out where to convert to or deploy from.
            File mavenDir = cmd.hasOption(OPTION_MAVEN_DIR) ?
                    new File(cmd.getOptionValue(OPTION_MAVEN_DIR)) : getTempDir("FLEX-MAVEN-");

            ////////////////////////////////////////////////////////////////////////////
            // Exectute operations
            ////////////////////////////////////////////////////////////////////////////

            // Get proxy settings from the commandline and save them in the
            // ProxySettings "singleton".
            ProxySettings proxySettings = getProxySettings(cmd);
            ProxySettings.setProxySettings(proxySettings);

            // Output a list of all available downloads.
            if(cmd.getArgList().contains(COMMAND_LIST)) {
                System.out.println("-----------------------------------------------");
                System.out.println("- Available downloads");
                System.out.println("-----------------------------------------------");

                DownloadRetriever retriever = new DownloadRetriever();
                System.out.println("Apache Flex:");
                List<DefaultArtifactVersion> versions = new ArrayList<DefaultArtifactVersion>(
                        retriever.getAvailableVersions(SdkType.FLEX).keySet());
                Collections.sort(versions);
                for(DefaultArtifactVersion version : versions) {
                    System.out.println(" - " + version.toString());
                }
                System.out.println();

                System.out.println("Adobe Flash:");
                versions = new ArrayList<DefaultArtifactVersion>(
                        retriever.getAvailableVersions(SdkType.FLASH).keySet());
                Collections.sort(versions);
                for(DefaultArtifactVersion version : versions) {
                    System.out.println(" - " + version.toString());
                }
                System.out.println();

                System.out.println("Adobe AIR:");
                Map<DefaultArtifactVersion, Collection<PlatformType>> versionData =
                        retriever.getAvailableVersions(SdkType.AIR);
                versions = new ArrayList<DefaultArtifactVersion>(versionData.keySet());
                Collections.sort(versions);
                for(DefaultArtifactVersion version : versions) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(" - ").append(version.toString()).append(" (");
                    boolean firstOption = true;
                    for(PlatformType platformType : versionData.get(version)) {
                        if(!firstOption) {
                            sb.append(", ");
                        }
                        sb.append(platformType.name());
                        firstOption = false;
                    }
                    sb.append(")");
                    System.out.println(sb.toString());
                }
            }

            // Handle the downloading of atifacts.
            if(cmd.getArgList().contains(COMMAND_DOWNLOAD)) {
                System.out.println("-----------------------------------------------");
                System.out.println("- Downloading");
                System.out.println("-----------------------------------------------");

                DownloadRetriever retriever = new DownloadRetriever();

                String flexVersion = cmd.getOptionValue(OPTION_FLEX_VERSION, null);
                if(flexVersion != null) {
                    System.out.println("- Downloading Flex SDK version: " + flexVersion +
                            " to directory: " + fdkDir.getAbsolutePath());
                    File fdkDownloadDirectory = retriever.retrieve(SdkType.FLEX, flexVersion);
                    // Unpack the archive to the FDK directory.
                    mergeDirectories(fdkDownloadDirectory, fdkDir);

                    // Add the swfobject files.
                    File swfObjectDirectory = retriever.retrieve(SdkType.SWFOBJECT);
                    mergeDirectories(swfObjectDirectory, fdkDir);
                }

                String flashVersions = cmd.getOptionValue(OPTION_FLASH_VERSIONS, "");
                if(!flashVersions.isEmpty()) {
                    for(String flashVersion : flashVersions.split(",")) {
                        System.out.println("- Downloading Flash SDK version: " + flashVersion +
                                " to directory: " + fdkDir.getAbsolutePath());
                        File flashDownloadDiretory = retriever.retrieve(SdkType.FLASH, flashVersion);
                        // Integrate the download into  the FDK directory.
                        mergeDirectories(flashDownloadDiretory, fdkDir);
                    }
                }

                String airVersion = cmd.getOptionValue(OPTION_AIT_VERSION, "");
                if(!airVersion.isEmpty()) {
                    for(PlatformType platformType : platforms) {
                        System.out.println("- Downloading Air SDK version: " + airVersion +
                                " and platform " + platformType.name() +
                                " to directory: " + fdkDir.getAbsolutePath());
                        File airDownloadDirectory = retriever.retrieve(SdkType.AIR, airVersion, platformType);
                        // Integrate the download into the FDK directory.
                        mergeDirectories(airDownloadDirectory, fdkDir);
                    }
                }

                if(cmd.hasOption(OPTION_FONTKIT)) {
                    System.out.println("- Downloading Flex Fontkit libraries" +
                            " to directory: " + fdkDir.getAbsolutePath());
                    File fontkitDownloadDirectory = retriever.retrieve(SdkType.FONTKIT);
                    // Integrate the download into the FDK directory.
                    mergeDirectories(fontkitDownloadDirectory, fdkDir);
                }

                System.out.println("Finished downloads.");
            }

            // Handle the conversion.
            if(cmd.getArgList().contains(COMMAND_CONVERT)) {
                System.out.println("-----------------------------------------------");
                System.out.println("- Conversion");
                System.out.println("-----------------------------------------------");

                System.out.println("- Converting Flex SDK from " + fdkDir.getAbsolutePath() +
                        " to " + mavenDir.getAbsolutePath());
                FlexConverter flexConverter = new FlexConverter(fdkDir, mavenDir);
                flexConverter.convert();

                System.out.println("- Converting Flash SDKs from " + fdkDir.getAbsolutePath() +
                        " to " + mavenDir.getAbsolutePath());
                FlashConverter flashConverter = new FlashConverter(fdkDir, mavenDir);
                flashConverter.convert();

                System.out.println("- Converting Air SDK from " + fdkDir.getAbsolutePath() +
                        " to " + mavenDir.getAbsolutePath());
                AirConverter airConverter = new AirConverter(fdkDir, mavenDir);
                airConverter.convert();

                System.out.println("- Converting Fontkit libraries from " + fdkDir.getAbsolutePath() +
                        " to " + mavenDir.getAbsolutePath());
                FontkitConverter fontkitConverter = new FontkitConverter(fdkDir, mavenDir);
                fontkitConverter.convert();

                System.out.println("- Converting Wrappers from " + fdkDir.getAbsolutePath() +
                        " to " + mavenDir.getAbsolutePath());
                WrapperConverter wrapperConverter = new WrapperConverter(fdkDir, mavenDir);
                wrapperConverter.convert();

                System.out.println("Finished conversion.");
            }

            // Handle the deployment.
            if(cmd.getArgList().contains(COMMAND_DEPLOY)) {
                System.out.println("-----------------------------------------------");
                System.out.println("- Deployment");
                System.out.println("-----------------------------------------------");

                if(!cmd.hasOption(OPTION_REPO_URL)) {
                    System.err.println("Parameter 'repoUrl' required for task 'deploy'.");
                    System.exit(1);
                }

                String repoUrl = cmd.getOptionValue(OPTION_REPO_URL);
                String repoUsername = cmd.getOptionValue(OPTION_REPO_USERNAME, null);
                String repoPassword = cmd.getOptionValue(OPTION_REPO_PASSWORD, null);

                System.out.println("- Deploying libraries to " + repoUrl + " from " + mavenDir.getAbsolutePath());

                AetherDeployer deployer = new AetherDeployer(mavenDir, repoUrl, repoUsername, repoPassword);
                deployer.deploy();

                System.out.println("Finished deploying.");
            }
            System.out.println("-----------------------------------------------");
        } catch (ParseException e) {
            System.err.println("Parsing failed. Reason: " + e.getMessage());
            printHelp(options);
        }
    }

    protected static void printHelp(Options options) {
        String headerText = "Commands: \n" +
                "If the parameters 'fdkDir' and 'mavenDir' are not specified, the Converter creates two temporary " +
                "directories in your systems temp directory and uses these for the follwoing commands.\n" +
                " - list:\nList all available versions and platforms (for download)\n" +
                " - download:\nDownload the selected versions of FDK parts specified by 'flexVersion', " +
                "'flashVersions', 'airVersion' and 'fontkit' and creates an FDK in the directory specified by " +
                "'fdkDir'. If 'airVersion' is specified, the 'platforms' parameter specifies the platforms for which " +
                "the given AIR SDK should be downloaded, if not specified the current systems platform is used. \n" +
                " - convert:\nConvert the FDK located in 'fdkDir' into a mavenized form at 'mavenDir'.\n" +
                " - deploy:\nDeploy the maven artifacts located in 'mavenDir', to the remote maven repository " +
                "specified with 'repoUrl'. If the 'repoUsername' and 'repoPassword' parameters are specified, use " +
                "these credentials for authenticating at the remote system.\n" +
                "Options:";

        HelpFormatter helpFormatter = new HelpFormatter();
        helpFormatter.printHelp("java -jar apache-flex-sdk-converter.jar [-proxyProtocol <http|https|socks> " +
                        "-proxyHost <host> -proxyPort <port> [-proxyNonProxyHost <non-proxy-host(s)>] " +
                        "[-proxyUser <username> -proxyPassword <password>]] [list] [-fdkDir <fdkDir>] " +
                        "[-mavenDir <mavenDir>] [[-flexVersion <version>] [-flashVersions <version(s)>] " +
                        "[-airVersion <version> [-platforms <platform(s)>]] [-fontkit] download] [convert] " +
                        "[-repoUrl <url> [-repoUsername <username> -repoPassword <password>] deploy]",
                headerText, options, "");
    }

    protected static File getTempDir(String prefix) throws IOException {
        File tempFile = File.createTempFile(prefix, ".TMP");
        tempFile.delete();
        File tempDir = new File(tempFile.getParentFile(),
                tempFile.getName().substring(0, tempFile.getName().length() - 4));
        if(!tempDir.exists()) {
            tempDir.mkdirs();
        }
        return tempDir;
    }

    protected static ProxySettings getProxySettings(CommandLine cmd) {
        if(cmd.hasOption(OPTION_PROXY_HOST)) {
            String protocol = cmd.getOptionValue(OPTION_PROXY_PROTOCOL);
            String host = cmd.getOptionValue(OPTION_PROXY_HOST);
            String nonProxyHost = cmd.getOptionValue(OPTION_PROXY_NON_PROXY_HOST);
            int port = cmd.hasOption(OPTION_PROXY_PORT) ? Integer.valueOf(cmd.getOptionValue(OPTION_PROXY_PORT)) : 0;
            String username = cmd.getOptionValue(OPTION_PROXY_USERNAME);
            String password = cmd.getOptionValue(OPTION_PROXY_PASSWORD);
            return new ProxySettings(protocol, host, port, nonProxyHost, username, password);
        }
        return null;
    }

    protected static void mergeDirectories(File sourceDir, File targetDir) throws IOException {
        FileUtils.copyDirectory(sourceDir, targetDir);
    }

}
