// Copyright 2006 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.analysis.stringtemplate;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for the {@link TemplateExpander}.
 */
@RunWith(JUnit4.class)
public class TemplateExpanderTest {
  private static final class TemplateContextImpl implements TemplateContext {
    private final Map<String, String> vars = new HashMap<>();
    private final Map<String, Function<String, String>> functions = new HashMap<>();

    @Override
    public String lookupVariable(String name)
        throws ExpansionException {
      // Not a Make variable. Let the shell handle the expansion.
      if (name.startsWith("$")) {
        return name;
      }
      if (!vars.containsKey(name)) {
        throw new ExpansionException(String.format("$(%s) not defined", name));
      }
      return vars.get(name);
    }

    @Override
    public String lookupFunction(String name, String param) throws ExpansionException {
      if (!functions.containsKey(name)) {
        throw new ExpansionException(String.format("$(%s) not defined", name));
      }
      return functions.get(name).apply(param);
    }
  }

  private TemplateContextImpl context;

  @Before
  public final void createContext() throws Exception  {
    context = new TemplateContextImpl();
  }

  private String expand(String value) throws ExpansionException {
    return TemplateExpander.expand(value, context);
  }

  private ExpansionException expansionFailure(String cmd) {
    try {
      expand(cmd);
      fail("Expansion of " + cmd + " didn't fail as expected");
      throw new AssertionError();
    } catch (ExpansionException e) {
      return e;
    }
  }

  @Test
  public void testVariableExpansion() throws Exception {
    context.vars.put("SRCS", "src1 src2");
    context.vars.put("<", "src1");
    context.vars.put("OUTS", "out1 out2");
    context.vars.put("@", "out1");
    context.vars.put("^", "src1 src2 dep1 dep2");
    context.vars.put("@D", "outdir");
    context.vars.put("BINDIR", "bindir");

    assertThat(expand("$(SRCS)")).isEqualTo("src1 src2");
    assertThat(expand("$<")).isEqualTo("src1");
    assertThat(expand("$(OUTS)")).isEqualTo("out1 out2");
    assertThat(expand("$(@)")).isEqualTo("out1");
    assertThat(expand("$@")).isEqualTo("out1");
    assertThat(expand("$@,")).isEqualTo("out1,");

    assertThat(expand("$(SRCS) $(OUTS)")).isEqualTo("src1 src2 out1 out2");

    assertThat(expand("cmd")).isEqualTo("cmd");
    assertThat(expand("cmd $(SRCS),")).isEqualTo("cmd src1 src2,");
    assertThat(expand("label1 $(SRCS),")).isEqualTo("label1 src1 src2,");
    assertThat(expand(":label1 $(SRCS),")).isEqualTo(":label1 src1 src2,");
  }

  @Test
  public void testUndefinedVariableExpansion() throws Exception {
    assertThat(expansionFailure("$(foo)"))
        .hasMessageThat().isEqualTo("$(foo) not defined");
  }

  @Test
  public void testFunctionExpansion() throws Exception {
    context.functions.put("foo", (String p) -> "FOO(" + p + ")");
    context.vars.put("bar", "bar");

    assertThat(expand("$(foo baz)")).isEqualTo("FOO(baz)");
    assertThat(expand("$(bar) $(foo baz)")).isEqualTo("bar FOO(baz)");
    assertThat(expand("xyz$(foo baz)zyx")).isEqualTo("xyzFOO(baz)zyx");
  }

  @Test
  public void testFunctionExpansionThrows() throws Exception {
    ExpansionException e =
        assertThrows(
            ExpansionException.class,
            () ->
                TemplateExpander.expand(
                    "$(foo baz)",
                    new TemplateContext() {
                      @Override
                      public String lookupVariable(String name) throws ExpansionException {
                        throw new ExpansionException(name);
                      }

                      @Override
                      public String lookupFunction(String name, String param)
                          throws ExpansionException {
                        throw new ExpansionException(name + "(" + param + ")");
                      }
                    }));
    assertThat(e).hasMessageThat().isEqualTo("foo(baz)");
  }

  @Test
  public void testUndefinedFunctionExpansion() throws Exception {
    // Note: $(location x) is considered an undefined variable;
    assertThat(expansionFailure("$(location label1), $(SRCS),"))
        .hasMessageThat().isEqualTo("$(location) not defined");
    assertThat(expansionFailure("$(basename file)"))
        .hasMessageThat().isEqualTo("$(basename) not defined");
  }

  @Test
  public void testRecursiveExpansion() throws Exception {
    // Expansion is recursive: $(recursive) -> $(SRCS) -> "src1 src2"
    context.vars.put("SRCS", "src1 src2");
    context.vars.put("recursive", "$(SRCS)");
    assertThat(expand("$(recursive)")).isEqualTo("src1 src2");
  }

  @Test
  public void testRecursiveExpansionDoesNotSpanExpansionBoundaries() throws Exception {
    // Recursion does not span expansion boundaries:
    // $(recur2a)$(recur2b) --> "$" + "(SRCS)"  --/--> "src1 src2"
    context.vars.put("SRCS", "src1 src2");
    context.vars.put("recur2a", "$$");
    context.vars.put("recur2b", "(SRCS)");
    assertThat(expand("$(recur2a)$(recur2b)")).isEqualTo("$(SRCS)");
  }

  @Test
  public void testSelfInfiniteExpansionFailsGracefully() throws Exception {
    context.vars.put("infinite", "$(infinite)");
    assertThat(expansionFailure("$(infinite)")).hasMessageThat()
        .isEqualTo("potentially unbounded recursion during expansion of '$(infinite)'");
  }

  @Test
  public void testMutuallyInfiniteExpansionFailsGracefully() throws Exception {
    context.vars.put("black", "$(white)");
    context.vars.put("white", "$(black)");
    assertThat(expansionFailure("$(white) is the new $(black)")).hasMessageThat()
        .isEqualTo("potentially unbounded recursion during expansion of '$(black)'");
  }

  @Test
  public void testErrors() throws Exception {
    assertThat(expansionFailure("$(SRCS")).hasMessageThat()
        .isEqualTo("unterminated variable reference");
    assertThat(expansionFailure("$")).hasMessageThat().isEqualTo("unterminated $");

    String suffix = "instead for \"Make\" variables, or escape the '$' as '$$' if you intended "
        + "this for the shell";
    assertThat(expansionFailure("for file in a b c;do echo $file;done")).hasMessageThat()
        .isEqualTo("'$file' syntax is not supported; use '$(file)' " + suffix);
    assertThat(expansionFailure("${file%:.*8}")).hasMessageThat()
        .isEqualTo("'${file%:.*8}' syntax is not supported; use '$(file%:.*8)' " + suffix);
  }

  @Test
  public void testDollarDollar() throws Exception {
    assertThat(expand("for file in a b c;do echo $$file;done"))
        .isEqualTo("for file in a b c;do echo $file;done");
    assertThat(expand("$${file%:.*8}")).isEqualTo("${file%:.*8}");
    assertThat(expand("$$(basename file)")).isEqualTo("$(basename file)");
  }

  // Regression test: check that the parameter is trimmed before expanding.
  @Test
  public void testFunctionExpansionIsTrimmed() throws Exception {
    context.functions.put("foo", (String p) -> "FOO(" + p + ")");
    assertThat(expand("$(foo  baz )")).isEqualTo("FOO(baz)");
  }
}
