/*
 * 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.FreeMarkerConstants.Configuration;
import org.apache.freemarker.generator.base.FreeMarkerConstants.SystemProperties;
import org.apache.freemarker.generator.base.parameter.ParameterModelSupplier;
import org.apache.freemarker.generator.base.util.ClosableUtils;
import org.apache.freemarker.generator.cli.config.Settings;
import org.apache.freemarker.generator.cli.config.Suppliers;
import org.apache.freemarker.generator.cli.picocli.GitVersionProvider;
import org.apache.freemarker.generator.cli.picocli.OutputGeneratorDefinition;
import org.apache.freemarker.generator.cli.task.FreeMarkerTask;
import picocli.CommandLine;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.Spec;

import java.io.File;
import java.io.Writer;
import java.util.ArrayList;
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.Collections.emptyList;
import static java.util.Objects.requireNonNull;
import static org.apache.freemarker.generator.base.util.StringUtils.isEmpty;
import static org.apache.freemarker.generator.base.util.StringUtils.isNotEmpty;

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

    @ArgGroup(exclusive = false, multiplicity = "1..*")
    List<OutputGeneratorDefinition> outputGeneratorDefinitions;

    @Option(names = { "--data-source-include" }, description = "data source include pattern")
    public String dataSourceIncludePattern;

    @Option(names = { "--data-source-exclude" }, description = "data source exclude pattern")
    public String dataSourceExcludePattern;

    @Option(names = { "--shared-data-model" }, description = "shared data models used for rendering")
    public List<String> sharedDataModels;

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

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

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

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

    @Option(names = { "--config" }, description = "FreeMarker Generator configuration file")
    String configFile;

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

    @Option(names = { "--stdin" }, description = "read data source from stdin")
    boolean readFromStdin;

    @Option(names = { "--template-dir" }, description = "additional template directory")
    String templateDir;

    @Option(names = { "--template-encoding" }, description = "template encoding", defaultValue = "UTF-8")
    String templateEncoding;

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

    @Parameters(description = "shared data source files and/or directories")
    List<String> sharedDataSources;

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

    /** User-supplied writer (used mainly for unit testing) */
    final Writer callerSuppliedWriter;

    /** Injected by Picocli */
    @Spec private CommandSpec spec;

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

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

    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() {
        validate();
        return IntStream.range(0, times).map(i -> onCall()).max().orElse(0);
    }

    private Integer onCall() {
        updateSystemProperties();

        final String currentConfigFile = isNotEmpty(configFile) ? configFile : getDefaultConfigFileName();
        final Properties configuration = loadFreeMarkerCliConfiguration(currentConfigFile);
        final List<File> templateDirectories = getTemplateDirectories(templateDir);
        final Settings settings = settings(configuration, templateDirectories, outputGeneratorDefinitions);

        try {
            final FreeMarkerTask freeMarkerTask = new FreeMarkerTask(
                    Suppliers.configurationSupplier(settings),
                    Suppliers.outputGeneratorsSupplier(settings),
                    Suppliers.sharedDataModelSupplier(settings),
                    Suppliers.sharedDataSourcesSupplier(settings),
                    settings::getUserParameters
            );
            return freeMarkerTask.call();
        } finally {
            ClosableUtils.closeQuietly(settings.getCallerSuppliedWriter());
        }
    }

    void validate() {
        outputGeneratorDefinitions.forEach(t -> t.validate(spec.commandLine()));
    }

    private Settings settings(Properties configuration, List<File> templateDirectories, List<OutputGeneratorDefinition> outputGeneratorDefinitions) {
        final ParameterModelSupplier parameterModelSupplier = new ParameterModelSupplier(parameters);

        return Settings.builder()
                .isReadFromStdin(readFromStdin)
                .setCommandLineArgs(args)
                .setConfiguration(configuration)
                .setTemplateDirectories(templateDirectories)
                .setTemplateEncoding(templateEncoding)
                .setOutputGeneratorDefinitions(outputGeneratorDefinitions)
                .setSharedDataSources(getSharedDataSources())
                .setSharedDataModels(sharedDataModels)
                .setSourceIncludePattern(dataSourceIncludePattern)
                .setSourceExcludePattern(dataSourceExcludePattern)
                .setInputEncoding(inputEncoding)
                .setLocale(locale)
                .setOutputEncoding(outputEncoding)
                .setParameters(parameterModelSupplier.get())
                .setSystemProperties(systemProperties != null ? systemProperties : new Properties())
                .setTemplateDirectories(templateDirectories)
                .setCallerSuppliedWriter(callerSuppliedWriter)
                .setVerbose(false)
                .build();
    }

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

    /**
     * Data sources can be passed via command line option and/or
     * positional parameter so we need to merge them.
     *
     * @return List of data sources
     */
    private List<String> getSharedDataSources() {
        return sharedDataSources != null ? new ArrayList<>(sharedDataSources) : emptyList();
    }

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

    /**
     * Get the default configuration file based on the "app.home" system property
     * provided by the shell wrapper.
     *
     * @return default configuration file name or null
     */
    private static String getDefaultConfigFileName() {
        final String appHome = System.getProperty(SystemProperties.APP_HOME);
        return isNotEmpty(appHome) ? new File(appHome, Configuration.CONFIG_FILE_NAME).getAbsolutePath() : null;
    }

    private static Properties loadFreeMarkerCliConfiguration(String fileName) {
        if (isEmpty(fileName)) {
            return new Properties();
        }

        final Properties properties = Suppliers.propertiesSupplier(fileName).get();
        if (properties != null) {
            return properties;
        } else {
            return new Properties();
        }
    }
}
