/*
 * 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.maven.plugins.jlink;

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

import java.io.File;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.shared.utils.cli.CommandLineException;
import org.apache.maven.shared.utils.cli.CommandLineUtils;
import org.apache.maven.shared.utils.cli.Commandline;
import org.apache.maven.toolchain.Toolchain;

abstract class AbstractJLinkToolchainExecutor extends AbstractJLinkExecutor {
    private final Toolchain toolchain;

    AbstractJLinkToolchainExecutor(Toolchain toolchain, Log log) {
        super(log);
        this.toolchain = toolchain;
    }

    protected Optional<Toolchain> getToolchain() {
        return Optional.ofNullable(this.toolchain);
    }

    /**
     * Execute JLink via toolchain.
     *
     * @return the exit code ({@code 0} on success).
     */
    @Override
    public int executeJlink(List<String> jlinkArgs) throws MojoExecutionException {
        File jlinkExecutable = getJlinkExecutable();
        getLog().info("Toolchain in maven-jlink-plugin: jlink [ " + jlinkExecutable + " ]");

        Commandline cmd = createJLinkCommandLine(jlinkArgs);
        cmd.setExecutable(jlinkExecutable.getAbsolutePath());

        return executeCommand(cmd);
    }

    private File getJlinkExecutable() {
        return new File(getJLinkExecutable());
    }

    @Override
    public Optional<File> getJmodsFolder(/* nullable */ File sourceJdkModules) {
        // Really Hacky...do we have a better solution to find the jmods directory of the JDK?
        File jLinkParent = getJlinkExecutable().getParentFile().getParentFile();
        File jmodsFolder;
        if (sourceJdkModules != null && sourceJdkModules.isDirectory()) {
            jmodsFolder = new File(sourceJdkModules, JMODS);
        } else {
            jmodsFolder = new File(jLinkParent, JMODS);
        }

        getLog().debug(" Parent: " + jLinkParent.getAbsolutePath());
        getLog().debug(" jmodsFolder: " + jmodsFolder.getAbsolutePath());

        return Optional.of(jmodsFolder);
    }

    private Commandline createJLinkCommandLine(List<String> jlinkArgs) {
        Commandline cmd = new Commandline();
        jlinkArgs.forEach(arg -> cmd.createArg().setValue("\"" + arg + "\""));

        return cmd;
    }

    private String getJLinkExecutable() {
        Optional<Toolchain> toolchain = getToolchain();

        if (!toolchain.isPresent()) {
            getLog().error("Either JDK9+ or a toolchain "
                    + "pointing to a JDK9+ containing a jlink binary is required.");
            getLog().info("See https://maven.apache.org/guides/mini/guide-using-toolchains.html "
                    + "for mor information.");
            throw new IllegalStateException("Running on JDK8 and no toolchain found.");
        }

        String jLinkExecutable =
                toolchain.orElseThrow(NoSuchElementException::new).findTool("jlink");

        if (jLinkExecutable.isEmpty()) {
            throw new IllegalStateException(
                    "The jlink executable '" + jLinkExecutable + "' doesn't exist or is not a file.");
        }

        // TODO: Check if there exist a more elegant way?
        String jLinkCommand = "jlink" + (SystemUtils.IS_OS_WINDOWS ? ".exe" : "");

        File jLinkExe = new File(jLinkExecutable);

        if (jLinkExe.isDirectory()) {
            jLinkExe = new File(jLinkExe, jLinkCommand);
        }

        if (SystemUtils.IS_OS_WINDOWS && jLinkExe.getName().indexOf('.') < 0) {
            jLinkExe = new File(jLinkExe.getPath() + ".exe");
        }

        if (!jLinkExe.isFile()) {
            throw new IllegalStateException("The jlink executable '" + jLinkExe + "' doesn't exist or is not a file.");
        }
        return jLinkExe.getAbsolutePath();
    }

    private int executeCommand(Commandline cmd) throws MojoExecutionException {
        if (getLog().isDebugEnabled()) {
            // no quoted arguments ???
            getLog().debug(CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", ""));
        }

        CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
        CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();
        try {
            int exitCode = CommandLineUtils.executeCommandLine(cmd, out, err);

            String output = StringUtils.isEmpty(out.getOutput())
                    ? null
                    : '\n' + out.getOutput().trim();

            if (exitCode != 0) {

                if (output != null && !output.isEmpty()) {
                    // Reconsider to use WARN / ERROR ?
                    //  getLog().error( output );
                    for (String outputLine : output.split("\n")) {
                        getLog().error(outputLine);
                    }
                }

                StringBuilder msg = new StringBuilder("\nExit code: ");
                msg.append(exitCode);
                if (StringUtils.isNotEmpty(err.getOutput())) {
                    msg.append(" - ").append(err.getOutput());
                }
                msg.append('\n');
                msg.append("Command line was: ").append(cmd).append('\n').append('\n');

                throw new MojoExecutionException(msg.toString());
            }

            if (output != null && !output.isEmpty()) {
                // getLog().info( output );
                for (String outputLine : output.split("\n")) {
                    getLog().info(outputLine);
                }
            }

            return exitCode;
        } catch (CommandLineException e) {
            throw new MojoExecutionException("Unable to execute jlink command: " + e.getMessage(), e);
        }
    }
}
