// Copyright 2017 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.skylark;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.vfs.ModifiedFileSet;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for string representations of Starlark objects. */
@RunWith(JUnit4.class)
public class StarlarkStringRepresentationsTest extends BuildViewTestCase {

  // Different ways to format objects, these suffixes are used in the `prepare_params` function
  private static final ImmutableList<String> SUFFIXES =
      ImmutableList.of("_str", "_repr", "_format", "_str_perc", "_repr_perc");

  private Object starlarkLoadingEval(String code) throws Exception {
    return starlarkLoadingEval(code, "");
  }

  /**
   * Evaluates {@code code} in the loading phase in a .bzl file
   *
   * @param code The code to execute
   * @param definition Additional code to define necessary variables
   */
  private Object starlarkLoadingEval(String code, String definition) throws Exception {
    scratch.overwriteFile("eval/BUILD", "load(':eval.bzl', 'eval')", "eval(name='eval')");
    scratch.overwriteFile(
        "eval/eval.bzl",
        definition,
        String.format("x = %s", code), // Should be placed here to execute during the loading phase
        "def _impl(ctx):",
        "  return struct(result = x)",
        "eval = rule(implementation = _impl)");
    skyframeExecutor.invalidateFilesUnderPathForTesting(
        reporter,
        new ModifiedFileSet.Builder()
            .modify(PathFragment.create("eval/BUILD"))
            .modify(PathFragment.create("eval/eval.bzl"))
            .build(),
        Root.fromPath(rootDirectory));

    ConfiguredTarget target = getConfiguredTarget("//eval");
    return target.get("result");
  }

  /**
   * Evaluates {@code code} in the loading phase in a BUILD file. {@code code} must return a string.
   *
   * @param code The code to execute
   */
  private Object starlarkLoadingEvalInBuildFile(String code) throws Exception {
    scratch.overwriteFile("eval/BUILD",
        "load(':eval.bzl', 'eval')",
        String.format("eval(name='eval', param = %s)", code));
    scratch.overwriteFile(
        "eval/eval.bzl",
        "def _impl(ctx):",
        "  return struct(result = ctx.attr.param)",
        "eval = rule(implementation = _impl, attrs = {'param': attr.string()})");
    skyframeExecutor.invalidateFilesUnderPathForTesting(
        reporter,
        new ModifiedFileSet.Builder()
            .modify(PathFragment.create("eval/BUILD"))
            .modify(PathFragment.create("eval/eval.bzl"))
            .build(),
        Root.fromPath(rootDirectory));

    ConfiguredTarget target = getConfiguredTarget("//eval");
    return target.get("result");
  }

  /**
   * Asserts that all 5 different ways to convert an object to a string of {@code expression}
   * ({@code str}, {@code repr}, {@code '%s'}, {@code '%r'}, {@code '{}'.format} return the correct
   * {@code representation}. Not applicable for objects that have different {@code str} and {@code
   * repr} representations.
   *
   * @param expression the expression to evaluate a string representation of
   * @param representation desired string representation
   */
  private void assertStringRepresentationInBuildFile(
      String expression, String representation) throws Exception {
    assertThat(starlarkLoadingEvalInBuildFile(String.format("str(%s)", expression)))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEvalInBuildFile(String.format("repr(%s)", expression)))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEvalInBuildFile(String.format("'%%s' %% (%s,)", expression)))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEvalInBuildFile(String.format("'%%r' %% (%s,)", expression)))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEvalInBuildFile(String.format("'{}'.format(%s)", expression)))
        .isEqualTo(representation);
  }

  /**
   * Asserts that all 5 different ways to convert an object to a string of {@code expression}
   * ({@code str}, {@code repr}, {@code '%s'}, {@code '%r'}, {@code '{}'.format} return the correct
   * {@code representation}. Not applicable for objects that have different {@code str} and {@code
   * repr} representations.
   *
   * @param definition optional definition required to evaluate the {@code expression}
   * @param expression the expression to evaluate a string representation of
   * @param representation desired string representation
   */
  private void assertStringRepresentation(
      String definition, String expression, String representation) throws Exception {
    assertThat(starlarkLoadingEval(String.format("str(%s)", expression), definition))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEval(String.format("repr(%s)", expression), definition))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEval(String.format("'%%s' %% (%s,)", expression), definition))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEval(String.format("'%%r' %% (%s,)", expression), definition))
        .isEqualTo(representation);
    assertThat(starlarkLoadingEval(String.format("'{}'.format(%s)", expression), definition))
        .isEqualTo(representation);
  }

  private void assertStringRepresentation(String expression, String representation)
      throws Exception {
    assertStringRepresentation("", expression, representation);
  }

  /**
   * Creates a set of BUILD and .bzl files that gathers objects of many different types available in
   * Starlark and creates their string representations by calling `str` and `repr` on them. The
   * strings are available in the configured target for //test/skylark:check
   */
  private void generateFilesToTestStrings() throws Exception {
    // Generate string representations of Starlark rule contexts, targets, and files.
    // Objects are gathered in the implementation of the `check` rule.
    // prepare_params(objects) converts a dict of objects to a dict of their string representations.

    scratch.file(
        "test/skylark/rules.bzl",
        "aspect_ctx_provider = provider()",
        "def prepare_params(objects):",
        "  params = {}",
        "  for k, v in objects.items():",
        "    params[k + '_str'] = str(v)",
        "    params[k + '_repr'] = repr(v)",
        "    params[k + '_format'] = '{}'.format(v)",
        "    params[k + '_str_perc'] = '%s' % (v,)",
        "    params[k + '_repr_perc'] = '%r' % (v,)",
        "  return params",
        "",
        "def _impl_aspect(target, ctx):",
        "  return [aspect_ctx_provider(ctx = ctx, rule = ctx.rule)]",
        "my_aspect = aspect(implementation = _impl_aspect)",
        "",
        "def _impl(ctx): pass",
        "dep = rule(implementation = _impl)",
        "",
        "def _genfile_impl(ctx):",
        "  ctx.actions.write(output = ctx.outputs.my_output, content = 'foo')",
        "genfile = rule(",
        "  implementation = _genfile_impl,",
        "  outputs = {'my_output': '%{name}.txt'},",
        ")",
        "",
        "def _check_impl(ctx):",
        "  source_file = ctx.attr.srcs[0].files.to_list()[0]",
        "  generated_file = ctx.attr.srcs[1].files.to_list()[0]",
        "  objects = {",
        "    'target': ctx.attr.deps[0],",
        "    'alias_target': ctx.attr.deps[1],",
        "    'aspect_target': ctx.attr.asp_deps[0],",
        "    'input_target': ctx.attr.srcs[0],",
        "    'output_target': ctx.attr.srcs[1],",
        "    'rule_ctx': ctx,",
        "    'aspect_ctx': ctx.attr.asp_deps[0][aspect_ctx_provider].ctx,",
        "    'aspect_ctx.rule': ctx.attr.asp_deps[0][aspect_ctx_provider].rule,",
        "    'source_file': source_file,",
        "    'generated_file': generated_file,",
        "    'source_root': source_file.root,",
        "    'generated_root': generated_file.root,",
        "  }",
        "  return struct(**prepare_params(objects))",
        "check = rule(",
        "  implementation = _check_impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'asp_deps': attr.label_list(aspects = [my_aspect]),",
        "    'srcs': attr.label_list(allow_files = True),",
        "  },",
        ")");

    scratch.file(
        "test/skylark/BUILD",
        "load(':rules.bzl', 'check', 'dep', 'genfile')",
        "",
        "dep(name = 'foo')",
        "dep(name = 'bar')",
        "alias(name = 'foobar', actual = ':foo')",
        "genfile(name = 'output')",
        "check(",
        "  name = 'check',",
        "  deps = [':foo', ':foobar'],",
        "  asp_deps = [':bar'],",
        "  srcs = ['input.txt', 'output.txt'],",
        ")");
  }

  @Test
  public void testStringRepresentations_Strings() throws Exception {
    assertThat(starlarkLoadingEval("str('foo')")).isEqualTo("foo");
    assertThat(starlarkLoadingEval("'%s' % 'foo'")).isEqualTo("foo");
    assertThat(starlarkLoadingEval("'{}'.format('foo')")).isEqualTo("foo");
    assertThat(starlarkLoadingEval("repr('foo')")).isEqualTo("\"foo\"");
    assertThat(starlarkLoadingEval("'%r' % 'foo'")).isEqualTo("\"foo\"");
  }

  @Test
  public void testStringRepresentations_Labels() throws Exception {
    assertThat(starlarkLoadingEval("str(Label('//foo:bar'))")).isEqualTo("//foo:bar");
    assertThat(starlarkLoadingEval("'%s' % Label('//foo:bar')")).isEqualTo("//foo:bar");
    assertThat(starlarkLoadingEval("'{}'.format(Label('//foo:bar'))")).isEqualTo("//foo:bar");
    assertThat(starlarkLoadingEval("repr(Label('//foo:bar'))")).isEqualTo("Label(\"//foo:bar\")");
    assertThat(starlarkLoadingEval("'%r' % Label('//foo:bar')")).isEqualTo("Label(\"//foo:bar\")");

    assertThat(starlarkLoadingEval("'{}'.format([Label('//foo:bar')])"))
        .isEqualTo("[Label(\"//foo:bar\")]");
  }

  @Test
  public void testStringRepresentations_Primitives() throws Exception {
    // Strings are tested in a separate test case as they have different str and repr values.
    assertStringRepresentation("1543", "1543");
    assertStringRepresentation("True", "True");
    assertStringRepresentation("False", "False");
  }

  @Test
  public void testStringRepresentations_Containers() throws Exception {
    assertStringRepresentation("['a', 'b']", "[\"a\", \"b\"]");
    assertStringRepresentation("('a', 'b')", "(\"a\", \"b\")");
    assertStringRepresentation("{'a': 'b', 'c': 'd'}", "{\"a\": \"b\", \"c\": \"d\"}");
    assertStringRepresentation("struct(d = 4, c = 3)", "struct(c = 3, d = 4)");
  }

  @Test
  public void testStringRepresentations_Functions() throws Exception {
    assertStringRepresentation("all", "<built-in function all>");
    assertStringRepresentation("def f(): pass", "f", "<function f from //eval:eval.bzl>");
  }

  @Test
  public void testStringRepresentations_Rules() throws Exception {
    assertStringRepresentation("native.cc_library", "<built-in rule cc_library>");
    assertStringRepresentation("def f(): pass", "rule(implementation=f)", "<rule>");
  }

  @Test
  public void testStringRepresentations_Aspects() throws Exception {
    assertStringRepresentation("def f(): pass", "aspect(implementation=f)", "<aspect>");
  }

  @Test
  public void testStringRepresentations_Providers() throws Exception {
    assertStringRepresentation("provider()", "<provider>");
    assertStringRepresentation(
        "p = provider()", "p(b = 'foo', a = 1)", "struct(a = 1, b = \"foo\")");
  }

  @Test
  public void testStringRepresentations_Select() throws Exception {
    assertStringRepresentation(
        "select({'//foo': ['//bar']}) + select({'//foo2': ['//bar2']})",
        "select({\"//foo\": [\"//bar\"]}) + select({\"//foo2\": [\"//bar2\"]})");
  }

  @Test
  public void testStringRepresentations_RuleContext() throws Exception {
    generateFilesToTestStrings();
    ConfiguredTarget target = getConfiguredTarget("//test/skylark:check");

    for (String suffix : SUFFIXES) {
      assertThat(target.get("rule_ctx" + suffix))
          .isEqualTo("<rule context for //test/skylark:check>");
      assertThat(target.get("aspect_ctx" + suffix))
          .isEqualTo("<aspect context for //test/skylark:bar>");
      assertThat(target.get("aspect_ctx.rule" + suffix))
          .isEqualTo("<rule collection for //test/skylark:bar>");
    }
  }

  @Test
  public void testStringRepresentations_Files() throws Exception {
    generateFilesToTestStrings();
    ConfiguredTarget target = getConfiguredTarget("//test/skylark:check");

    for (String suffix : SUFFIXES) {
      assertThat(target.get("source_file" + suffix))
          .isEqualTo("<source file test/skylark/input.txt>");
      assertThat(target.get("generated_file" + suffix))
          .isEqualTo("<generated file test/skylark/output.txt>");
    }
  }

  @Test
  public void testStringRepresentations_Root() throws Exception {
    generateFilesToTestStrings();
    ConfiguredTarget target = getConfiguredTarget("//test/skylark:check");

    for (String suffix : SUFFIXES) {
      assertThat(target.get("source_root" + suffix)).isEqualTo("<source root>");
      assertThat(target.get("generated_root" + suffix)).isEqualTo("<derived root>");
    }
  }

  @Test
  public void testStringRepresentations_Glob() throws Exception {
    scratch.file("eval/one.txt");
    scratch.file("eval/two.txt");
    scratch.file("eval/three.txt");

    assertStringRepresentationInBuildFile(
        "glob(['*.txt'])",
        "[\"one.txt\", \"three.txt\", \"two.txt\"]");
  }

  @Test
  public void testStringRepresentations_Attr() throws Exception {
    assertStringRepresentation("attr", "<attr>");
    assertStringRepresentation("attr.int()", "<attr.int>");
    assertStringRepresentation("attr.string()", "<attr.string>");
    assertStringRepresentation("attr.label()", "<attr.label>");
    assertStringRepresentation("attr.string_list()", "<attr.string_list>");
    assertStringRepresentation("attr.int_list()", "<attr.int_list>");
    assertStringRepresentation("attr.label_list()", "<attr.label_list>");
    assertStringRepresentation("attr.label_keyed_string_dict()", "<attr.label_keyed_string_dict>");
    assertStringRepresentation("attr.bool()", "<attr.bool>");
    assertStringRepresentation("attr.output()", "<attr.output>");
    assertStringRepresentation("attr.output_list()", "<attr.output_list>");
    assertStringRepresentation("attr.string_dict()", "<attr.string_dict>");
    assertStringRepresentation("attr.string_list_dict()", "<attr.string_list_dict>");
  }

  @Test
  public void testStringRepresentations_Targets() throws Exception {
    generateFilesToTestStrings();
    ConfiguredTarget target = getConfiguredTarget("//test/skylark:check");

    for (String suffix : SUFFIXES) {
      assertThat(target.get("target" + suffix))
          .isEqualTo("<target //test/skylark:foo>");
      assertThat(target.get("input_target" + suffix))
          .isEqualTo("<input file target //test/skylark:input.txt>");
      assertThat(target.get("output_target" + suffix))
          .isEqualTo("<output file target //test/skylark:output.txt>");
      assertThat(target.get("alias_target" + suffix))
          .isEqualTo("<alias target //test/skylark:foobar of //test/skylark:foo>");
      assertThat(target.get("aspect_target" + suffix))
          .isEqualTo("<merged target //test/skylark:bar>");
    }
  }
}
