/*
 * 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.freemarker.generator.cli;

import org.apache.freemarker.generator.base.util.ClosableUtils;
import org.apache.freemarker.generator.base.util.StringUtils;
import org.apache.freemarker.generator.cli.config.Settings;
import org.apache.freemarker.generator.cli.picocli.GitVersionProvider;
import org.apache.freemarker.generator.cli.task.FreeMarkerTask;
import picocli.CommandLine;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.stream.IntStream;

import static java.util.Objects.requireNonNull;
import static org.apache.freemarker.generator.cli.config.Suppliers.propertiesSupplier;
import static org.apache.freemarker.generator.cli.config.Suppliers.templateDirectorySupplier;

@Command(description = "Apache FreeMarker CLI", name = "freemarker-cli", mixinStandardHelpOptions = true, versionProvider = GitVersionProvider.class)
public class Main implements Callable<Integer> {

    private static final String FREEMARKER_CLI_PROPERTY_FILE = "freemarker-cli.properties";

    @ArgGroup(multiplicity = "1")
    private TemplateSourceOptions templateSourceOptions;

    private static final class TemplateSourceOptions {
        @Option(names = { "-t", "--template" }, description = "FreeMarker template to render")
        private String template;

        @Option(names = { "-i", "--interactive" }, description = "Interactive FreeMarker template")
        private String interactiveTemplate;
    }

    @Option(names = { "-b", "--basedir" }, description = "Optional template base directory")
    private String baseDir;

    @Option(names = { "-D", "--system-property" }, description = "Set system property")
    private Properties systemProperties;

    @Option(names = { "-e", "--input-encoding" }, description = "Encoding of input documents", defaultValue = "UTF-8")
    private String inputEncoding;

    @Option(names = { "-E", "--expose-env" }, description = "Expose environment variables and user-supplied properties globally")
    private boolean isEnvironmentExposed;

    @Option(names = { "-l", "--locale" }, description = "Locale being used for the output, e.g. 'en_US'")
    private String locale;

    @Option(names = { "-o", "--output" }, description = "Output file")
    private String outputFile;

    @Option(names = { "-P", "--param" }, description = "Set parameter")
    private Map<String, String> parameters;

    @Option(names = { "--config" }, defaultValue = FREEMARKER_CLI_PROPERTY_FILE, description = "FreeMarker CLI configuration file")
    private String configFile;

    @Option(names = { "--include" }, description = "File pattern for document input directory")
    private String include;

    @Option(names = { "--exclude" }, description = "File pattern for document input directory")
    private String exclude;

    @Option(names = { "--output-encoding" }, description = "Encoding of output, e.g. UTF-8", defaultValue = "UTF-8")
    private String outputEncoding;

    @Option(names = { "--stdin" }, description = "Read input document from stdin")
    private boolean readFromStdin;

    @Option(names = { "--times" }, defaultValue = "1", description = "Re-run X times for profiling")
    private int times;

    @Parameters(description = "List of input files and/or input directories")
    private List<String> sources;

    /** User-supplied command line parameters */
    private final String[] args;

    /** User-supplied writer (used mainly for unit testing) */
    private Writer userSuppliedWriter;

    private Main(String[] args) {
        this.args = requireNonNull(args);
    }

    private Main(String[] args, Writer userSuppliedWriter) {
        this.args = requireNonNull(args);
        this.userSuppliedWriter = requireNonNull(userSuppliedWriter);
    }

    public static void main(String[] args) {
        try {
            System.exit(execute(args));
        } catch (RuntimeException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    public static int execute(String[] args) {
        return new CommandLine(new Main(args)).execute(args);
    }

    /**
     * Used for testing to inject a writer.
     *
     * @param args   command line parameters
     * @param writer writer used for template rendering
     * @return exit code
     */
    public static int execute(String[] args, Writer writer) {
        return new CommandLine(new Main(args, writer)).execute(args);
    }

    @Override
    public Integer call() {
        return IntStream.range(0, times).map(i -> onCall()).max().orElse(0);
    }

    private Integer onCall() {
        updateSystemProperties();

        final Properties configuration = loadFreeMarkerCliConfiguration(configFile);
        final List<File> templateDirectories = getTemplateDirectories(baseDir);
        final Settings settings = settings(configuration, templateDirectories);

        try {
            final FreeMarkerTask freeMarkerTask = new FreeMarkerTask(settings);
            return freeMarkerTask.call();
        } finally {
            if (settings.hasOutputFile()) {
                ClosableUtils.closeQuietly(settings.getWriter());
            }
        }
    }

    private Settings settings(Properties configuration, List<File> templateDirectories) {
        return Settings.builder()
                .isEnvironmentExposed(isEnvironmentExposed)
                .isReadFromStdin(readFromStdin)
                .setArgs(args)
                .setConfiguration(configuration)
                .setInclude(include)
                .setExclude(exclude)
                .setInputEncoding(inputEncoding)
                .setInteractiveTemplate(templateSourceOptions.interactiveTemplate)
                .setLocale(locale)
                .setOutputEncoding(outputEncoding)
                .setOutputFile(outputFile)
                .setParameters(parameters != null ? parameters : new HashMap<>())
                .setSources(sources != null ? sources : new ArrayList<>())
                .setSystemProperties(systemProperties != null ? systemProperties : new Properties())
                .setTemplateDirectories(templateDirectories)
                .setTemplateName(templateSourceOptions.template)
                .setWriter(writer(outputFile, outputEncoding))
                .build();
    }

    private Writer writer(String outputFile, String ouputEncoding) {
        try {
            if (userSuppliedWriter != null) {
                return userSuppliedWriter;
            } else if (!StringUtils.isEmpty(outputFile)) {
                return new BufferedWriter(new FileWriter(outputFile));
            } else {
                return new BufferedWriter(new OutputStreamWriter(System.out, ouputEncoding));
            }
        } catch (IOException e) {
            throw new RuntimeException("Unable to create writer", e);
        }
    }

    private void updateSystemProperties() {
        if (systemProperties != null && !systemProperties.isEmpty()) {
            System.getProperties().putAll(systemProperties);
        }
    }

    private static List<File> getTemplateDirectories(String baseDir) {
        return templateDirectorySupplier(baseDir).get();
    }

    private static Properties loadFreeMarkerCliConfiguration(String fileName) {
        final Properties properties = propertiesSupplier(fileName).get();
        if (properties != null) {
            return properties;
        } else {
            throw new RuntimeException("FreeMarker CLI configuration file not found: " + fileName);
        }
    }
}
