package org.apache.s4.tools;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;

public class CreateApp extends S4ArgsBase {

    static Logger logger = LoggerFactory.getLogger(CreateApp.class);

    public static void main(String[] args) {

        final CreateAppArgs appArgs = new CreateAppArgs();
        Tools.parseArgs(appArgs, args);

        if (new File(appArgs.getAppDir() + "/" + appArgs.appName.get(0)).exists()) {
            System.err.println("There is already a directory called " + appArgs.appName.get(0) + " in the "
                    + appArgs.getAppDir()
                    + " directory. Please specify another name for your project or specify another parent directory");
            System.exit(1);
        }
        // create project structure
        try {
            createDir(appArgs, "/src/main/java");
            createDir(appArgs, "/src/main/resources");
            createDir(appArgs, "/src/main/java/hello");

            // copy gradlew script (redirecting to s4 gradlew)
            File gradlewTempFile = File.createTempFile("gradlew", "tmp");
            gradlewTempFile.deleteOnExit();
            Files.copy(Resources.newInputStreamSupplier(Resources.getResource("templates/gradlew")), gradlewTempFile);
            String gradlewScriptContent = Files.readLines(gradlewTempFile, Charsets.UTF_8, new PathsReplacer(appArgs));
            Files.write(gradlewScriptContent, gradlewTempFile, Charsets.UTF_8);
            Files.copy(gradlewTempFile, new File(appArgs.getAppDir() + "/gradlew"));
            new File(appArgs.getAppDir() + "/gradlew").setExecutable(true);

            // copy build file
            Files.copy(Resources.newInputStreamSupplier(Resources.getResource("templates/build.gradle")), new File(
                    appArgs.getAppDir() + "/build.gradle"));
            // copy hello app files
            Files.copy(Resources.newInputStreamSupplier(Resources.getResource("templates/HelloPE.java.txt")), new File(
                    appArgs.getAppDir() + "/src/main/java/hello/HelloPE.java"));
            Files.copy(Resources.newInputStreamSupplier(Resources.getResource("templates/HelloApp.java.txt")),
                    new File(appArgs.getAppDir() + "/src/main/java/hello/HelloApp.java"));
            // copy hello app adapter
            Files.copy(Resources.newInputStreamSupplier(Resources.getResource("templates/HelloInputAdapter.java.txt")),
                    new File(appArgs.getAppDir() + "/src/main/java/hello/HelloInputAdapter.java"));

            File s4TmpFile = File.createTempFile("s4Script", "template");
            s4TmpFile.deleteOnExit();
            Files.copy(Resources.newInputStreamSupplier(Resources.getResource("templates/s4")), s4TmpFile);

            // create s4
            String preparedS4Script = Files.readLines(s4TmpFile, Charsets.UTF_8, new PathsReplacer(appArgs));

            File s4Script = new File(appArgs.getAppDir() + "/s4");
            Files.write(preparedS4Script, s4Script, Charsets.UTF_8);
            s4Script.setExecutable(true);

            File readmeTmpFile = File.createTempFile("newApp", "README");
            readmeTmpFile.deleteOnExit();
            Files.copy(Resources.newInputStreamSupplier(Resources.getResource("templates/newApp.README")),
                    readmeTmpFile);
            // display contents from readme
            Files.readLines(readmeTmpFile, Charsets.UTF_8, new LineProcessor<Boolean>() {

                @Override
                public boolean processLine(String line) throws IOException {
                    System.out.println(line.replace("<appDir>", appArgs.getAppDir()));
                    return true;
                }

                @Override
                public Boolean getResult() {
                    return true;
                }

            });
        } catch (Exception e) {
            logger.error("Could not create project due to [{}]. Please check your configuration.", e.getMessage());
            logger.error("Could not create project due to [{}]. Please check your configuration.", e.getMessage());
        }
    }

    private static void createDir(CreateAppArgs appArgs, String dirName) throws Exception {
        String filePath = appArgs.getAppDir() + dirName;
        if (!new File(filePath).mkdirs()) {
            logger.error("Cannot create directory [{}], exiting.", filePath);
            throw new Exception("Cannot create directory [" + filePath + "]");
        }
    }

    private static final class PathsReplacer implements LineProcessor<String> {
        private final CreateAppArgs appArgs;
        StringBuilder sb = new StringBuilder();

        private PathsReplacer(CreateAppArgs appArgs) {
            this.appArgs = appArgs;
        }

        @Override
        public boolean processLine(String line) throws IOException {
            sb.append(line.replace("<s4_script_path>", appArgs.s4ScriptPath).replace("<s4_install_dir>",
                    new File(appArgs.s4ScriptPath).getParent())
                    + "\n");
            return true;
        }

        @Override
        public String getResult() {
            return sb.toString();
        }
    }

    @Parameters(commandNames = "newApp", separators = "=", commandDescription = "Create new application skeleton")
    static class CreateAppArgs extends S4ArgsBase {

        @Parameter(description = "name of the application", required = true, arity = 1)
        List<String> appName;

        @Parameter(names = "-parentDir", description = "parent directory of the application")
        String parentDir = System.getProperty("user.dir");

        public String getAppDir() {
            return parentDir + "/" + appName.get(0);
        }

    }
}
