// 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.packages;

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

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.AttributeValueGetter;
import com.google.devtools.build.lib.testutil.Suite;
import com.google.devtools.build.lib.testutil.TestSpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link ImplicitOutputsFunction}.
 */
@TestSpec(size = Suite.SMALL_TESTS)
@RunWith(JUnit4.class)
public final class ImplicitOutputsFunctionTest {
  private void assertPlaceholderCollection(
      String template, String expectedTemplate, String... expectedPlaceholders) throws Exception {
    List<String> actualPlaceholders = new ArrayList<>();
    assertThat(
            ImplicitOutputsFunction.createPlaceholderSubstitutionFormatString(
                template, actualPlaceholders))
        .isEqualTo(expectedTemplate);
    assertThat(actualPlaceholders)
        .containsExactlyElementsIn(Arrays.asList(expectedPlaceholders))
        .inOrder();
  }

  @Test
  public void testNoPlaceholder() throws Exception {
    assertPlaceholderCollection("foo", "foo");
  }

  @Test
  public void testJustPlaceholder() throws Exception {
    assertPlaceholderCollection("%{foo}", "%s", "foo");
  }

  @Test
  public void testPrefixedPlaceholder() throws Exception {
    assertPlaceholderCollection("foo%{bar}", "foo%s", "bar");
  }

  @Test
  public void testSuffixedPlaceholder() throws Exception {
    assertPlaceholderCollection("%{foo}bar", "%sbar", "foo");
  }

  @Test
  public void testMultiplePlaceholdersPrefixed() throws Exception {
    assertPlaceholderCollection("foo%{bar}baz%{qux}", "foo%sbaz%s", "bar", "qux");
  }

  @Test
  public void testMultiplePlaceholdersSuffixed() throws Exception {
    assertPlaceholderCollection("%{foo}bar%{baz}qux", "%sbar%squx", "foo", "baz");
  }

  @Test
  public void testTightlyPackedPlaceholders() throws Exception {
    assertPlaceholderCollection("%{foo}%{bar}%{baz}", "%s%s%s", "foo", "bar", "baz");
  }

  @Test
  public void testIncompletePlaceholder() throws Exception {
    assertPlaceholderCollection("%{foo", "%%{foo");
  }

  @Test
  public void testCompleteAndIncompletePlaceholder() throws Exception {
    assertPlaceholderCollection("%{foo}%{bar", "%s%%{bar", "foo");
  }

  @Test
  public void testPlaceholderLooksLikeNestedIncompletePlaceholder() throws Exception {
    assertPlaceholderCollection("%{%{foo", "%%{%%{foo");
  }

  @Test
  public void testPlaceholderLooksLikeNestedPlaceholder() throws Exception {
    assertPlaceholderCollection("%{%{foo}", "%s", "%{foo");
  }

  @Test
  public void testEscapesJustPercentSign() throws Exception {
    assertPlaceholderCollection("%", "%%");
  }

  @Test
  public void testEscapesPrintfPlaceholder() throws Exception {
    assertPlaceholderCollection("%{x}%s%{y}", "%s%%s%s", "x", "y");
  }

  @Test
  public void testEscapesPercentSign() throws Exception {
    assertPlaceholderCollection("foo%{bar}%baz", "foo%s%%baz", "bar");
  }

  private static AttributeValueGetter attrs(
      final Map<String, ? extends Collection<String>> values) {
    return new AttributeValueGetter() {
      @Override
      public Set<String> get(AttributeMap ignored, String attr) {
        return new LinkedHashSet<>(Preconditions.checkNotNull(values.get(attr)));
      }
    };
  }

  private void assertPlaceholderSubtitution(
      String template,
      AttributeValueGetter attrValues,
      String[] expectedSubstitutions,
      String[] expectedFoundPlaceholders)
      throws Exception {
    List<String> foundAttributes = new ArrayList<>();
    List<String> substitutions =
        ImplicitOutputsFunction.substitutePlaceholderIntoTemplate(
            template, null, attrValues, foundAttributes);
    assertThat(foundAttributes)
        .containsExactlyElementsIn(Arrays.asList(expectedFoundPlaceholders))
        .inOrder();
    assertThat(substitutions)
        .containsExactlyElementsIn(Arrays.asList(expectedSubstitutions));
  }

  @Test
  public void testSingleScalarElementSubstitution() throws Exception {
    assertPlaceholderSubtitution(
        "%{x}",
        attrs(ImmutableMap.of("x", ImmutableList.of("a"))),
        new String[] {"a"},
        new String[] {"x"});
  }

  @Test
  public void testSingleVectorElementSubstitution() throws Exception {
    assertPlaceholderSubtitution(
        "%{x}",
        attrs(ImmutableMap.of("x", ImmutableList.of("a", "b", "c"))),
        new String[] {"a", "b", "c"},
        new String[] {"x"});
  }

  @Test
  public void testMultipleElementsSubstitution() throws Exception {
    assertPlaceholderSubtitution(
        "%{x}-%{y}-%{z}",
        attrs(
            ImmutableMap.of(
                "x", ImmutableList.of("foo", "bar", "baz"),
                "y", ImmutableList.of("meow"),
                "z", ImmutableList.of("1", "2"))),
        new String[] {
          "foo-meow-1", "foo-meow-2", "bar-meow-1", "bar-meow-2", "baz-meow-1", "baz-meow-2"
        },
        new String[] {"x", "y", "z"});
  }

  @Test
  public void testEmptyElementSubstitution() throws Exception {
    assertPlaceholderSubtitution(
        "a-%{x}",
        attrs(ImmutableMap.of("x", ImmutableList.<String>of())),
        new String[0],
        new String[] {"x"});
  }

  @Test
  public void testSamePlaceholderMultipleTimes() throws Exception {
    assertPlaceholderSubtitution(
        "%{x}-%{y}-%{x}",
        attrs(ImmutableMap.of("x", ImmutableList.of("a", "b"), "y", ImmutableList.of("1", "2"))),
        new String[] {"a-1-a", "a-1-b", "a-2-a", "a-2-b", "b-1-a", "b-1-b", "b-2-a", "b-2-b"},
        new String[] {"x", "y", "x"});
  }

  @Test
  public void testRepeatingPlaceholderValue() throws Exception {
    assertPlaceholderSubtitution(
        "%{x}",
        attrs(ImmutableMap.of("x", ImmutableList.of("a", "a"))),
        new String[] {"a"},
        new String[] {"x"});
  }

  @Test
  public void testIncompletePlaceholderTreatedAsText() throws Exception {
    assertPlaceholderSubtitution(
        "%{x}-%{y-%{z",
        attrs(ImmutableMap.of("x", ImmutableList.of("a", "b"))),
        new String[] {"a-%{y-%{z", "b-%{y-%{z"},
        new String[] {"x"});
  }
}
