package cn.ibizlab.codegen;

import cn.ibizlab.codegen.config.CodegenConfigurator;
import cn.ibizlab.codegen.config.CodegenConfiguratorUtils;
import cn.ibizlab.codegen.config.EmbedTemplate;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.StringUtils.isNotEmpty;

/**
 * 生成文件
 * 
 * @author YangHu, tangguo
 * @since 2016/8/30
 */
@Mojo(name = "code", threadSafe = true)
public class GenerateMojo extends AbstractMojo {



	@Parameter
	private String output ;

	@Parameter
	private String inputSpec;

	@Parameter
	private String[] inputSpecfilters;

	@Parameter
	private String[] templateDirs;


	@Parameter
	private String[] templatePaths;


	@Parameter
	private String[] templateFilters;

	@Parameter
	private String auth;

	@Parameter
	private String[] globalProperties ;


	@Parameter
	private String name;

	@Parameter
	private String packageName;



	@Parameter
	private String[] additionalProperties ;






	/**
	 * 日志工具
	 */
	protected Log log = getLog();

	CodegenConfigurator configurator;
	Generator generator;


	@Override
	public void execute() throws MojoExecutionException, MojoFailureException {
		// this initial check allows for field-level package private injection (for unit testing)
		if (configurator == null) {

			// if a config file wasn't specified, or we were unable to read it
			if (configurator == null) {
				// create a fresh configurator
				configurator = new CodegenConfigurator();
			}
		}



		if (isNotEmpty(inputSpec)) {
			if (!inputSpec.matches("^http(s)?://.*") && !new File(inputSpec).exists()) {
				getLog().error("[error] The spec file is not found: " + inputSpec);
				getLog().error("[error] Check the path of the ibizlab-Model spec and try again.");
				return;
			}
			configurator.setInputSpec(inputSpec);
		}



		if (isNotEmpty(output)) {
			configurator.setOutputDir(output);
		}

		if (isNotEmpty(auth)) {
			configurator.setAuth(auth);
		}

		if (!ObjectUtils.isEmpty(templateDirs)) {
			configurator.setTemplateDirs(Arrays.asList(templateDirs));
		}

		if (!ObjectUtils.isEmpty(templatePaths)) {
			configurator.setTemplatePaths(Arrays.asList(templatePaths));
		}

		if (!ObjectUtils.isEmpty(templateFilters)) {
			configurator.setTemplateFilters(Arrays.asList(templateFilters));
		}

		if (!ObjectUtils.isEmpty(templateFilters)) {
			configurator.setFilters(Arrays.asList(templateFilters));
		}

		if (isNotEmpty(packageName)) {
			configurator.setPackageName(packageName);
		}

		if (isNotEmpty(name)) {
			configurator.setProjectName(name);
		}




		if (!ObjectUtils.isEmpty(globalProperties))  {
			CodegenConfiguratorUtils.applyGlobalPropertiesKvpList(Arrays.asList(globalProperties), configurator);
		}

		if (!ObjectUtils.isEmpty(additionalProperties))  {
			CodegenConfiguratorUtils.applyAdditionalPropertiesKvpList(Arrays.asList(additionalProperties), configurator);
		}



		try {

			// this null check allows us to inject for unit testing.
			if (generator == null) {
				generator = new DefaultGenerator();
			}

			generator.opts(configurator.toClientOptInput());
			generator.generate();
		} catch (GeneratorNotFoundException e) {
			getLog().error(e.getMessage());
			getLog().error("[error] Check the spelling of the generator's name and try again.");
			return;
		}
	}



}
