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

import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.Map;
import java.util.Properties;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.junit.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import freemarker.cache.FileTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Mocked;
import mockit.Verifications;

public class FreeMarkerMojoTest extends Assert {

  private static final File TEST_OUTPUT_DIR = new File("target/test-output/freemarker-mojo");
  private static final String FREEMARKER_VERSION = "2.3.29";
  
  @BeforeClass
  public static void beforeClass() throws IOException {
    // Clean output dir before each run.
    if (TEST_OUTPUT_DIR.exists()) {
      // Recursively delete output from previous run.
      Files.walk(TEST_OUTPUT_DIR.toPath())
       .sorted(Comparator.reverseOrder())
       .map(Path::toFile)
       .forEach(File::delete);
    }
  }

  @Test
  public void executeTest(
      @Mocked MavenSession session,
      @Mocked MavenProject project,
      @Mocked MojoExecution mojoExecution,
      @Mocked GeneratingFileVisitor generatingFileVisitor,
      @Mocked Files files
      ) throws MojoExecutionException, MojoFailureException, IOException {

    new Expectations(mojoExecution, generatingFileVisitor) {{
      mojoExecution.getLifecyclePhase(); result = "generate-sources";
      session.getCurrentProject(); result = project;
    }};

    FreeMarkerMojo mojo = new FreeMarkerMojo();
    
    // Validate freeMarkerVersion is required.
    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("freeMarkerVersion is required");
    
    Deencapsulation.setField(mojo, "freeMarkerVersion", "");
    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("freeMarkerVersion is required");

    File testCaseOutputDir = new File(TEST_OUTPUT_DIR, "executeTest");
    Deencapsulation.setField(mojo, "freeMarkerVersion", FREEMARKER_VERSION);
    Deencapsulation.setField(mojo, "sourceDirectory", testCaseOutputDir);
    Deencapsulation.setField(mojo, "templateDirectory", new File(testCaseOutputDir, "template"));
    Deencapsulation.setField(mojo, "generatorDirectory", new File(testCaseOutputDir, "data"));
    Deencapsulation.setField(mojo, "outputDirectory", new File(testCaseOutputDir, "generated-files"));
    Deencapsulation.setField(mojo, "mojo", mojoExecution);
    Deencapsulation.setField(mojo, "session", session);

    // Validate source directory.
    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("Required directory does not exist: target/test-output/freemarker-mojo/executeTest/data");
    
    new File(testCaseOutputDir, "data").mkdirs();
    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("Required directory does not exist: target/test-output/freemarker-mojo/executeTest/template");
    new File(testCaseOutputDir, "template").mkdirs();
    
    // Validate minimum configuration.
    mojo.execute();
    
    new Verifications() {{
      project.addCompileSourceRoot("target/test-output/freemarker-mojo/executeTest/generated-files"); times = 1;

      Configuration config;
      MavenSession capturedSession;
      Map<String, OutputGeneratorPropertiesProvider> builders;

      GeneratingFileVisitor.create(
          config = withCapture(), 
          capturedSession = withCapture(), 
          builders = withCapture()); times = 1;

      assertEquals("UTF-8", config.getDefaultEncoding());
      assertEquals(session, capturedSession);
      TemplateLoader loader = config.getTemplateLoader();
      assertTrue(loader instanceof FileTemplateLoader);

      Path path;
      FileVisitor<Path> fileVisitor;
      
      Files.walkFileTree(path = withCapture(), fileVisitor = withCapture()); times = 1;
      
      assertEquals(new File(testCaseOutputDir, "data").toPath(), path);
      assertTrue(fileVisitor instanceof GeneratingFileVisitor);
    }};
  }
  
  @Test
  public void execute_generateTestSourceTest(
      @Mocked MavenSession session,
      @Mocked MavenProject project,
      @Mocked MojoExecution mojoExecution,
      @Mocked GeneratingFileVisitor generatingFileVisitor,
      @Mocked Files files
      ) throws MojoExecutionException, MojoFailureException, IOException {

    new Expectations(mojoExecution, generatingFileVisitor) {{
      mojoExecution.getLifecyclePhase(); result = "generate-test-sources";
      session.getCurrentProject(); result = project;
    }};

    FreeMarkerMojo mojo = new FreeMarkerMojo();
    
    File testCaseOutputDir = new File(TEST_OUTPUT_DIR, "generateTestSourceTest");
    Deencapsulation.setField(mojo, "freeMarkerVersion", FREEMARKER_VERSION);
    Deencapsulation.setField(mojo, "sourceDirectory", testCaseOutputDir);
    Deencapsulation.setField(mojo, "templateDirectory", new File(testCaseOutputDir, "template"));
    Deencapsulation.setField(mojo, "generatorDirectory", new File(testCaseOutputDir, "data"));
    Deencapsulation.setField(mojo, "outputDirectory", new File(testCaseOutputDir, "generated-files"));
    Deencapsulation.setField(mojo, "mojo", mojoExecution);
    Deencapsulation.setField(mojo, "session", session);

    new File(testCaseOutputDir, "data").mkdirs();
    new File(testCaseOutputDir, "template").mkdirs();
    
    mojo.execute();
    
    new Verifications() {{
      project.addTestCompileSourceRoot("target/test-output/freemarker-mojo/generateTestSourceTest/generated-files"); times = 1;
    }};
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  @Test
  public void execute_walkFileTreeExceptionTest(
      @Mocked MavenSession session,
      @Mocked MavenProject project,
      @Mocked MojoExecution mojoExecution,
      @Mocked GeneratingFileVisitor generatingFileVisitor,
      @Mocked Files files
      ) throws MojoExecutionException, MojoFailureException, IOException {

    new Expectations(mojoExecution, generatingFileVisitor) {{
      mojoExecution.getLifecyclePhase(); result = "generate-test-sources";
      session.getCurrentProject(); result = project;
      Files.walkFileTree((Path) any,(FileVisitor) any); result = new RuntimeException("test exception");
    }};

    FreeMarkerMojo mojo = new FreeMarkerMojo();
    
    File testCaseOutputDir = new File(TEST_OUTPUT_DIR, "generateTestSourceTest");
    Deencapsulation.setField(mojo, "freeMarkerVersion", FREEMARKER_VERSION);
    Deencapsulation.setField(mojo, "sourceDirectory", testCaseOutputDir);
    Deencapsulation.setField(mojo, "templateDirectory", new File(testCaseOutputDir, "template"));
    Deencapsulation.setField(mojo, "generatorDirectory", new File(testCaseOutputDir, "data"));
    Deencapsulation.setField(mojo, "outputDirectory", new File(testCaseOutputDir, "generated-files"));
    Deencapsulation.setField(mojo, "mojo", mojoExecution);
    Deencapsulation.setField(mojo, "session", session);

    new File(testCaseOutputDir, "data").mkdirs();
    new File(testCaseOutputDir, "template").mkdirs();
    
    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("Failed to process files in generator dir: target/test-output/freemarker-mojo/generateTestSourceTest/data");
  }
  
  @Test
  public void execute_setTemplateLoaderExceptionTest(
      @Mocked MavenSession session,
      @Mocked MavenProject project,
      @Mocked MojoExecution mojoExecution,
      @Mocked FactoryUtil factoryUtil,
      @Mocked Configuration config) {
    
    new Expectations(config, FactoryUtil.class) {{
      FactoryUtil.createConfiguration(FREEMARKER_VERSION); result = config;
      config.setTemplateLoader((TemplateLoader) any); result = new RuntimeException("test exception");
    }};

    FreeMarkerMojo mojo = new FreeMarkerMojo();

    File testCaseOutputDir = new File(TEST_OUTPUT_DIR, "setTemplateLoaderException");

    Deencapsulation.setField(mojo, "freeMarkerVersion", FREEMARKER_VERSION);
    Deencapsulation.setField(mojo, "sourceDirectory", testCaseOutputDir);
    Deencapsulation.setField(mojo, "templateDirectory", new File(testCaseOutputDir, "template"));
    Deencapsulation.setField(mojo, "generatorDirectory", new File(testCaseOutputDir, "data"));
    Deencapsulation.setField(mojo, "outputDirectory", new File(testCaseOutputDir, "generated-files"));
    Deencapsulation.setField(mojo, "mojo", mojoExecution);
    Deencapsulation.setField(mojo, "session", session);

    new File(testCaseOutputDir, "data").mkdirs();
    new File(testCaseOutputDir, "template").mkdirs();

    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("Could not establish file template loader for directory: target/test-output/freemarker-mojo/setTemplateLoaderException/template");
  }
  
  @Test
  public void execute_loadFreemarkerPropertiesTest(
      @Mocked MavenSession session,
      @Mocked MavenProject project,
      @Mocked MojoExecution mojoExecution,
      @Mocked Configuration config) throws Exception {
    
    FreeMarkerMojo mojo = new FreeMarkerMojo();

    File sourceDirectory = new File("src/test/data/freemarker-mojo");
    File testCaseOutputDir = new File(TEST_OUTPUT_DIR, "loadFreemarkerProperties");

    Deencapsulation.setField(mojo, "freeMarkerVersion", FREEMARKER_VERSION);
    Deencapsulation.setField(mojo, "sourceDirectory", sourceDirectory);
    Deencapsulation.setField(mojo, "templateDirectory", new File( sourceDirectory, "template"));
    Deencapsulation.setField(mojo, "generatorDirectory", new File( sourceDirectory, "data"));
    Deencapsulation.setField(mojo, "outputDirectory", new File(testCaseOutputDir, "generated-files"));
    Deencapsulation.setField(mojo, "mojo", mojoExecution);
    Deencapsulation.setField(mojo, "session", session);

    mojo.execute();
    
    new Verifications() {{
      Properties properties;
      
      config.setSettings(properties = withCapture()); times = 1;
      
      assertEquals("T,F", properties.getProperty("boolean_format"));
    }};
  }
  
  @Test
  public void execute_loadFreemarkerPropertiesExceptionTest(
      @Mocked MavenSession session,
      @Mocked MavenProject project,
      @Mocked MojoExecution mojoExecution,
      @Mocked FactoryUtil factoryUtil,
      @Mocked Configuration config) throws Exception {
    
    new Expectations(FactoryUtil.class) {{
      FactoryUtil.createFileInputStream((File) any); result = new RuntimeException("test exception");
    }};
    
    FreeMarkerMojo mojo = new FreeMarkerMojo();

    File sourceDirectory = new File("src/test/data/freemarker-mojo");
    File testCaseOutputDir = new File(TEST_OUTPUT_DIR, "loadFreemarkerPropertiesExceptionTest");

    Deencapsulation.setField(mojo, "freeMarkerVersion", FREEMARKER_VERSION);
    Deencapsulation.setField(mojo, "sourceDirectory", sourceDirectory);
    Deencapsulation.setField(mojo, "templateDirectory", new File( sourceDirectory, "template"));
    Deencapsulation.setField(mojo, "generatorDirectory", new File( sourceDirectory, "data"));
    Deencapsulation.setField(mojo, "outputDirectory", new File(testCaseOutputDir, "generated-files"));
    Deencapsulation.setField(mojo, "mojo", mojoExecution);
    Deencapsulation.setField(mojo, "session", session);

    System.out.println("==== before mojo execute");
    try {
    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("Failed to load src/test/data/freemarker-mojo/freemarker.properties");
    } catch ( Throwable t) {
      t.printStackTrace();
    }
  }

  @Test
  public void execute_setSettingsExceptionTest(
      @Mocked MavenSession session,
      @Mocked MavenProject project,
      @Mocked MojoExecution mojoExecution,
      @Mocked Configuration config) throws Exception {
    
    new Expectations() {{
      config.setSettings((Properties) any); result = new RuntimeException("test exception");
    }};
    
    FreeMarkerMojo mojo = new FreeMarkerMojo();

    File sourceDirectory = new File("src/test/data/freemarker-mojo");
    File testCaseOutputDir = new File(TEST_OUTPUT_DIR, "loadFreemarkerProperties");

    Deencapsulation.setField(mojo, "freeMarkerVersion", FREEMARKER_VERSION);
    Deencapsulation.setField(mojo, "sourceDirectory", sourceDirectory);
    Deencapsulation.setField(mojo, "templateDirectory", new File( sourceDirectory, "template"));
    Deencapsulation.setField(mojo, "generatorDirectory", new File( sourceDirectory, "data"));
    Deencapsulation.setField(mojo, "outputDirectory", new File(testCaseOutputDir, "generated-files"));
    Deencapsulation.setField(mojo, "mojo", mojoExecution);
    Deencapsulation.setField(mojo, "session", session);

    assertThatExceptionOfType(MojoExecutionException.class).isThrownBy(() -> {
      mojo.execute();
    }).withMessage("Invalid setting(s) in src/test/data/freemarker-mojo/freemarker.properties");
  }
  
}
