// Copyright 2015 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.syntax;

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

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.util.Arrays;
import java.util.IllegalFormatException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 *  Test properties of the evaluator's datatypes and utility functions
 *  without actually creating any parse trees.
 */
@RunWith(JUnit4.class)
public class PrinterTest {

  @Test
  public void testPrinter() throws Exception {
    // Note that prettyPrintValue and printValue only differ on behaviour of
    // labels and strings at toplevel.
    assertThat(Printer.str("foo\nbar")).isEqualTo("foo\nbar");
    assertThat(Printer.repr("foo\nbar")).isEqualTo("\"foo\\nbar\"");
    assertThat(Printer.str("'")).isEqualTo("'");
    assertThat(Printer.repr("'")).isEqualTo("\"'\"");
    assertThat(Printer.str("\"")).isEqualTo("\"");
    assertThat(Printer.repr("\"")).isEqualTo("\"\\\"\"");
    assertThat(Printer.str(3)).isEqualTo("3");
    assertThat(Printer.repr(3)).isEqualTo("3");
    assertThat(Printer.repr(Runtime.NONE)).isEqualTo("None");

    assertThat(Printer.str(Label.parseAbsolute("//x"))).isEqualTo("//x:x");
    assertThat(Printer.repr(Label.parseAbsolute("//x"))).isEqualTo("Label(\"//x:x\")");

    List<?> list = MutableList.of(null, "foo", "bar");
    List<?> tuple = Tuple.of("foo", "bar");

    assertThat(Printer.str(Tuple.of(1, list, 3))).isEqualTo("(1, [\"foo\", \"bar\"], 3)");
    assertThat(Printer.repr(Tuple.of(1, list, 3))).isEqualTo("(1, [\"foo\", \"bar\"], 3)");
    assertThat(Printer.str(MutableList.of(null, 1, tuple, 3)))
        .isEqualTo("[1, (\"foo\", \"bar\"), 3]");
    assertThat(Printer.repr(MutableList.of(null, 1, tuple, 3)))
        .isEqualTo("[1, (\"foo\", \"bar\"), 3]");

    Map<Object, Object> dict = ImmutableMap.<Object, Object>of(
        1, tuple,
        2, list,
        "foo", MutableList.of(null));
    assertThat(Printer.str(dict))
        .isEqualTo("{1: (\"foo\", \"bar\"), 2: [\"foo\", \"bar\"], \"foo\": []}");
    assertThat(Printer.repr(dict))
        .isEqualTo("{1: (\"foo\", \"bar\"), 2: [\"foo\", \"bar\"], \"foo\": []}");
  }

  private void checkFormatPositionalFails(String errorMessage, String format, Object... arguments) {
    try {
      Printer.format(format, arguments);
      fail();
    } catch (IllegalFormatException e) {
      assertThat(e).hasMessage(errorMessage);
    }
  }

  @Test
  public void testOutputOrderOfMap() throws Exception {
    Map<Object, Object> map = new LinkedHashMap<>();
    map.put(5, 5);
    map.put(3, 3);
    map.put("foo", 42);
    map.put(7, "bar");
    assertThat(Printer.str(map)).isEqualTo("{5: 5, 3: 3, \"foo\": 42, 7: \"bar\"}");
  }

  @Test
  public void testFormatPositional() throws Exception {
    assertThat(Printer.formatWithList("%s %d", Tuple.of("foo", 3))).isEqualTo("foo 3");
    assertThat(Printer.format("%s %d", "foo", 3)).isEqualTo("foo 3");

    // Note: formatToString doesn't perform scalar x -> (x) conversion;
    // The %-operator is responsible for that.
    assertThat(Printer.formatWithList("", Tuple.of())).isEmpty();
    assertThat(Printer.format("%s", "foo")).isEqualTo("foo");
    assertThat(Printer.format("%s", 3.14159)).isEqualTo("3.14159");
    checkFormatPositionalFails("not all arguments converted during string formatting",
        "%s", 1, 2, 3);
    assertThat(Printer.format("%%%s", "foo")).isEqualTo("%foo");
    checkFormatPositionalFails("not all arguments converted during string formatting",
        "%%s", "foo");
    checkFormatPositionalFails("unsupported format character \" \" at index 1 in \"% %s\"",
        "% %s", "foo");
    assertThat(Printer.format("%s", MutableList.of(null, 1, 2, 3))).isEqualTo("[1, 2, 3]");
    assertThat(Printer.format("%s", Tuple.of(1, 2, 3))).isEqualTo("(1, 2, 3)");
    assertThat(Printer.format("%s", MutableList.of(null))).isEqualTo("[]");
    assertThat(Printer.format("%s", Tuple.of())).isEqualTo("()");
    assertThat(Printer.format("%% %d %r %s", 1, "2", "3")).isEqualTo("% 1 \"2\" 3");

    checkFormatPositionalFails(
        "invalid argument \"1\" for format pattern %d",
        "%d", "1");
    checkFormatPositionalFails("unsupported format character \".\" at index 1 in \"%.3g\"",
        "%.3g");
    checkFormatPositionalFails("unsupported format character \".\" at index 1 in \"%.3g\"",
        "%.3g", 1, 2);
    checkFormatPositionalFails("unsupported format character \".\" at index 1 in \"%.s\"",
        "%.s");
  }

  @Test
  public void testListLimitStringLength() throws Exception {
    int lengthDivisibleByTwo = Printer.SUGGESTED_CRITICAL_LIST_ELEMENTS_STRING_LENGTH;
    if (lengthDivisibleByTwo % 2 == 1) {
      ++lengthDivisibleByTwo;
    }
    String limit = Strings.repeat("x", lengthDivisibleByTwo);
    String half = Strings.repeat("x", lengthDivisibleByTwo / 2);

    List<String> list = Arrays.asList(limit + limit);

    // String is way too long -> shorten.
    assertThat(printListWithLimit(list)).isEqualTo("[\"" + limit + "...\"]");

    LinkedList<List<String>> nestedList = new LinkedList<>();
    nestedList.add(list);

    // Same as above, but with one additional level of indirection.
    assertThat(printListWithLimit(nestedList)).isEqualTo("[[\"" + limit + "...\"]]");

    // The inner list alone would meet the limit, but because of the first element, it has to be
    // shortened.
    assertThat(printListWithLimit(Arrays.asList(half, Arrays.asList(limit))))
        .isEqualTo("[\"" + half + "\", [\"" + half + "...\"]]");

    // String is too long, but the ellipsis make it even longer.
    assertThat(printListWithLimit(Arrays.asList(limit + "x"))).isEqualTo("[\"" + limit + "...\"]");

    // We hit the limit exactly -> everything is printed.
    assertThat(printListWithLimit(Arrays.asList(limit))).isEqualTo("[\"" + limit + "\"]");

    // Exact hit, but with two arguments -> everything is printed.
    assertThat(printListWithLimit(Arrays.asList(half, half)))
        .isEqualTo("[\"" + half + "\", \"" + half + "\"]");

    // First argument hits the limit -> remaining argument is shortened.
    assertThat(printListWithLimit(Arrays.asList(limit, limit)))
        .isEqualTo("[\"" + limit + "\", \"...\"]");

    String limitMinusOne = limit.substring(0, limit.length() - 1);

    // First arguments is one below the limit -> print first character of remaining argument.
    assertThat(printListWithLimit(Arrays.asList(limitMinusOne, limit)))
        .isEqualTo("[\"" + limitMinusOne + "\", \"x...\"]");

    // First argument hits the limit -> we skip  the remaining two arguments.
    assertThat(printListWithLimit(Arrays.asList(limit, limit, limit)))
        .isEqualTo("[\"" + limit + "\", <2 more arguments>]");
  }

  @Test
  public void testListLimitTooManyArgs() throws Exception {
    StringBuilder builder = new StringBuilder();
    List<Integer> maxLength = new LinkedList<>();

    int next;
    for (next = 0; next < Printer.SUGGESTED_CRITICAL_LIST_ELEMENTS_COUNT; ++next) {
      maxLength.add(next);
      if (next > 0) {
        builder.append(", ");
      }
      builder.append(next);
    }

    // There is one too many, but we print every argument nonetheless.
    maxLength.add(next);
    assertThat(printListWithLimit(maxLength)).isEqualTo("[" + builder + ", " + next + "]");

    // There are two too many, hence we don't print them.
    ++next;
    maxLength.add(next);
    assertThat(printListWithLimit(maxLength)).isEqualTo("[" + builder + ", <2 more arguments>]");
  }

  @Test
  public void testPrintListDefaultNoLimit() throws Exception {
    List<Integer> list = new LinkedList<>();
    // Make sure that the resulting string is longer than the suggestion. This should also lead to
    // way more items than suggested.
    for (int i = 0; i < Printer.SUGGESTED_CRITICAL_LIST_ELEMENTS_STRING_LENGTH * 2; ++i) {
      list.add(i);
    }
    assertThat(Printer.str(list)).isEqualTo(String.format("[%s]", Joiner.on(", ").join(list)));
  }

  @Test
  public void testLegacyPrinter() throws Exception {
    assertThat(new Printer.LegacyPrinter().str(createObjWithStr()).toString())
        .isEqualTo("<str legacy marker>");
    assertThat(new Printer.LegacyPrinter().repr(createObjWithStr()).toString())
        .isEqualTo("<repr legacy marker>");
  }

  private String printListWithLimit(List<?> list) {
    return printList(list, Printer.SUGGESTED_CRITICAL_LIST_ELEMENTS_COUNT,
        Printer.SUGGESTED_CRITICAL_LIST_ELEMENTS_STRING_LENGTH);
  }

  private String printList(List<?> list, int criticalElementsCount, int criticalStringLength) {
    return Printer.printAbbreviatedList(
        list, "[", ", ", "]", "", criticalElementsCount, criticalStringLength);
  }

  private SkylarkValue createObjWithStr() {
    return new SkylarkValue() {
      @Override
      public void repr(SkylarkPrinter printer) {
        printer.append("<repr marker>");
      }

      @Override
      public void reprLegacy(SkylarkPrinter printer) {
        printer.append("<repr legacy marker>");
      }

      @Override
      public void str(SkylarkPrinter printer) {
        printer.append("<str marker>");
      }

      @Override
      public void strLegacy(SkylarkPrinter printer) {
        printer.append("<str legacy marker>");
      }
    };
  }
}
