// Copyright (C) 2020 The Android Open Source Project
//
// Licensed 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 com.googlesource.gerrit.plugins.its.base.workflow;

import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.ProvisionException;
import com.googlesource.gerrit.plugins.its.base.ItsPath;
import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.UUID;
import org.eclipse.jgit.util.FileUtils;
import org.junit.Test;

public class AddSoyCommentTest extends LoggingMockingTestCase {
  private Injector injector;

  private ItsFacade its;
  private boolean cleanupSitePath;
  private Path itsPath;

  @Test
  public void testNoTemplateFileParameter() throws IOException {
    ActionRequest actionRequest = new ActionRequest("foo");

    AddSoyComment addSoyComment = createAddSoyComment();
    addSoyComment.execute(its, "4711", actionRequest, ImmutableMap.of());

    assertLogMessageContains("No template");
  }

  @Test
  public void testTemplateFileDoesNotExist() {
    ActionRequest actionRequest = new ActionRequest("foo nonExistingTemplate");

    AddSoyComment addSoyComment = createAddSoyComment();

    assertThrows(
        ProvisionException.class,
        () -> addSoyComment.execute(its, "4711", actionRequest, ImmutableMap.of()));
  }

  @Test
  public void testPlain() throws IOException {
    String templateName = "plain";

    ActionRequest actionRequest = new ActionRequest("foo " + templateName);

    injectTemplate(templateName, "bar");

    AddSoyComment addSoyComment = createAddSoyComment();
    addSoyComment.execute(its, "4711", actionRequest, ImmutableMap.of());

    verify(its).addComment("4711", "bar");
  }

  @Test
  public void testParameterPlain() throws IOException {
    String templateName = "parameterPlain";

    ActionRequest actionRequest = new ActionRequest("foo " + templateName);
    Map<String, String> properties =
        ImmutableMap.<String, String>builder().put("param1", "simple").build();

    injectTemplate(templateName, "{@param param1:string}{$param1}");

    AddSoyComment addSoyComment = createAddSoyComment();
    addSoyComment.execute(its, "4711", actionRequest, properties);

    verify(its).addComment("4711", "simple");
  }

  @Test
  public void testParameterEscapingDefault() throws IOException {
    String templateName = "parameterEscapingDefault";

    ActionRequest actionRequest = new ActionRequest("foo " + templateName);
    Map<String, String> properties =
        ImmutableMap.<String, String>builder().put("param1", "<b>bar\"/>").build();

    injectTemplate(templateName, "{@param param1:string}{$param1}");

    AddSoyComment addSoyComment = createAddSoyComment();
    addSoyComment.execute(its, "4711", actionRequest, properties);

    verify(its).addComment("4711", "&lt;b&gt;bar&quot;/&gt;");
  }

  @Test
  public void testParameterEscapingTextUnescaped() throws IOException {
    String templateName = "parameterEscapingTextUnescaped";

    ActionRequest actionRequest = new ActionRequest("foo " + templateName);
    Map<String, String> properties =
        ImmutableMap.<String, String>builder().put("param1", "<b>bar\"/>").build();

    injectTemplate(templateName, "text", "{@param param1:string}{$param1}");

    AddSoyComment addSoyComment = createAddSoyComment();
    addSoyComment.execute(its, "4711", actionRequest, properties);

    verify(its).addComment("4711", "<b>bar\"/>");
  }

  @Test
  public void testParameterEscapingTextForcedEscapingUri() throws IOException {
    String templateName = "parameterEscapingTextForcedEscapingUri";

    ActionRequest actionRequest = new ActionRequest("foo " + templateName);
    Map<String, String> properties =
        ImmutableMap.<String, String>builder().put("param1", "<b>bar\"/>").build();

    injectTemplate(templateName, "text", "{@param param1:string}{$param1|escapeUri}");

    AddSoyComment addSoyComment = createAddSoyComment();
    addSoyComment.execute(its, "4711", actionRequest, properties);

    verify(its).addComment("4711", "%3Cb%3Ebar%22%2F%3E");
  }

  private AddSoyComment createAddSoyComment() {
    return injector.getInstance(AddSoyComment.class);
  }

  @Override
  public void setUp() throws Exception {
    super.setUp();
    cleanupSitePath = false;
    injector = Guice.createInjector(new TestModule());
  }

  @Override
  public void tearDown() throws Exception {
    if (cleanupSitePath) {
      if (Files.exists(itsPath)) {
        FileUtils.delete(itsPath.toFile(), FileUtils.RECURSIVE);
      }
    }
    super.tearDown();
  }

  private void injectTemplate(String name, String content) throws IOException {
    injectTemplate(name, null, content);
  }

  private void injectTemplate(String name, String kind, String content) throws IOException {
    Path templatePath = itsPath.resolve("templates").resolve(name + ".soy");
    Files.createDirectories(templatePath.getParent());
    String namespace = "{namespace etc.its.templates}";
    String opening = "{template ." + name + (kind != null ? (" kind=\"" + kind + "\"") : "") + "}";
    String closing = "{/template}";

    String fullTemplate = namespace + opening + content + closing;

    Files.write(templatePath, fullTemplate.getBytes());
  }

  private Path randomTargetPath() {
    return Paths.get("target", "random_name_" + UUID.randomUUID().toString().replaceAll("-", "_"));
  }

  private class TestModule extends FactoryModule {
    @Override
    protected void configure() {
      its = mock(ItsFacade.class);
      bind(ItsFacade.class).toInstance(its);

      itsPath = randomTargetPath().resolve("etc").resolve("its");
      assertFalse("itsPath (" + itsPath + ") already exists", Files.exists(itsPath));
      cleanupSitePath = true;
      bind(Path.class).annotatedWith(ItsPath.class).toInstance(itsPath);
    }
  }
}
