// Copyright 2023 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.docgen;

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

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.devtools.build.docgen.BuildDocCollector.DocumentationOrigin;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ModuleInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.OriginKey;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for BuildDocCollector. */
@RunWith(JUnit4.class)
public final class BuildDocCollectorTest {

  // The following are initialized by setUpCollectorState to simplify boilerplate.
  Map<String, DocumentationOrigin> ruleDocOrigin;
  Map<String, RuleDocumentation> ruleDocEntries;
  ListMultimap<String, RuleDocumentationAttribute> attributeDocEntries;
  SourceUrlMapper urlMapper =
      new SourceUrlMapper(
          /* sourceUrlRoot= */ "https://example.com/",
          /* inputRoot= */ "/tmp/io_bazel/",
          ImmutableMap.of("@_builtins//:", "//src/main/starlark/builtins_bzl:"));

  @Before
  public void setUpCollectorState() {
    ruleDocOrigin = new HashMap<>();
    ruleDocEntries = new HashMap<>();
    attributeDocEntries = LinkedListMultimap.create();
  }

  private int collectModuleInfoDocs(ModuleInfo moduleInfo) throws Exception {
    return BuildDocCollector.collectModuleInfoDocs(
        ruleDocOrigin,
        ruleDocEntries,
        ImmutableSet.of(),
        attributeDocEntries,
        moduleInfo,
        urlMapper);
  }

  private int collectModuleInfoDocsWithDenyList(ModuleInfo moduleInfo, Set<String> denyList)
      throws Exception {
    return BuildDocCollector.collectModuleInfoDocs(
        ruleDocOrigin, ruleDocEntries, denyList, attributeDocEntries, moduleInfo, urlMapper);
  }

  @Nullable
  private RuleDocumentationAttribute getAttribute(
      Set<RuleDocumentationAttribute> attributes, String name) {
    for (RuleDocumentationAttribute attribute : attributes) {
      if (attribute.getAttributeName().equals(name)) {
        return attribute;
      }
    }
    return null;
  }

  @Test
  public void collectModuleInfoDocs_basicFunctionality() throws Exception {
    ModuleInfo moduleInfo =
        ModuleInfo.newBuilder()
            .setModuleDocstring("My Language")
            .setFile("//:test.bzl")
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("binary_rules.my_binary")
                    .setDocString("My language binary")
                    .setExecutable(true)
                    .setOriginKey(
                        OriginKey.newBuilder()
                            .setName("_my_binary")
                            .setFile("@_builtins//:my_lang/my_binary.bzl"))
                    .addAttribute(
                        // starlark_doc_extract always injects the implicit "name" attribute
                        AttributeInfo.newBuilder()
                            .setName("name")
                            .setType(AttributeType.NAME)
                            .setMandatory(true)
                            .setDocString("A unique name for this target.")
                            .build())
                    .addAttribute(
                        AttributeInfo.newBuilder()
                            .setName("srcs")
                            .setDocString("My sources")
                            .setType(AttributeType.LABEL_LIST)
                            .setMandatory(true))
                    .addAttribute(
                        AttributeInfo.newBuilder()
                            .setName("deps")
                            .setDocString("My deps")
                            .setType(AttributeType.LABEL_LIST)
                            .setDefaultValue("[]"))
                    .addAttribute(
                        AttributeInfo.newBuilder()
                            .setName("old")
                            .setDocString("Deprecated: do not use")
                            .setType(AttributeType.STRING)
                            .setDefaultValue("\"???\"")))
            .build();

    assertThat(collectModuleInfoDocs(moduleInfo)).isEqualTo(1);

    assertThat(ruleDocEntries.keySet()).containsExactly("my_binary");

    RuleDocumentation ruleDoc = ruleDocEntries.get("my_binary");
    assertThat(ruleDoc.getRuleName()).isEqualTo("my_binary");
    assertThat(ruleDoc.getRuleType()).isEqualTo(DocgenConsts.RuleType.BINARY);
    assertThat(ruleDoc.getRuleFamily()).isEqualTo("My Language");
    assertThat(ruleDoc.getFamilySummary()).isEmpty();
    assertThat(ruleDoc.getSourceUrl())
        .isEqualTo("https://example.com/src/main/starlark/builtins_bzl/my_lang/my_binary.bzl");
    assertThat(ruleDoc.getHtmlDocumentation()).isEqualTo("My language binary");
    Set<RuleDocumentationAttribute> attributes = ruleDoc.getAttributes();
    assertThat(attributes)
        .containsAtLeastElementsIn(PredefinedAttributes.COMMON_ATTRIBUTES.values());
    assertThat(attributes)
        .containsAtLeastElementsIn(PredefinedAttributes.BINARY_ATTRIBUTES.values());
    assertThat(
            attributes.stream()
                .map(RuleDocumentationAttribute::getAttributeName)
                .filter(
                    attr ->
                        !(PredefinedAttributes.COMMON_ATTRIBUTES.containsKey(attr)
                            || PredefinedAttributes.BINARY_ATTRIBUTES.containsKey(attr))))
        // We do not want the implicit "name" attribute - we inject "name" at template level
        .containsExactly("srcs", "deps", "old");

    RuleDocumentationAttribute srcsAttribute = getAttribute(attributes, "srcs");
    assertThat(srcsAttribute.getAttributeName()).isEqualTo("srcs");
    assertThat(srcsAttribute.getHtmlDocumentation()).isEqualTo("My sources");
    assertThat(srcsAttribute.getSynopsis())
        .isEqualTo("List of <a href=\"${link build-ref#labels}\">labels</a>; required");

    RuleDocumentationAttribute depsAttribute = getAttribute(attributes, "deps");
    assertThat(depsAttribute.getAttributeName()).isEqualTo("deps");
    assertThat(depsAttribute.getHtmlDocumentation()).isEqualTo("My deps");
    assertThat(depsAttribute.getSynopsis())
        .isEqualTo(
            "List of <a href=\"${link build-ref#labels}\">labels</a>; default is <code>[]</code>");

    RuleDocumentationAttribute oldAttribute = getAttribute(attributes, "old");
    assertThat(oldAttribute.getAttributeName()).isEqualTo("old");
    assertThat(oldAttribute.isDeprecated()).isTrue();
    assertThat(oldAttribute.getSynopsis()).isEqualTo("String; default is <code>\"???\"</code>");

    assertThat(ruleDocOrigin)
        .containsExactly(
            "my_binary", DocumentationOrigin.create("//:test.bzl", "binary_rules.my_binary"));
  }

  @Test
  public void collectModuleInfoDocs_respectsDenyList() throws Exception {
    ModuleInfo moduleInfo =
        ModuleInfo.newBuilder()
            .setModuleDocstring("My Language")
            .setFile("//:test.bzl")
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("library_rules.my_library")
                    .setDocString("My language library")
                    .setOriginKey(
                        OriginKey.newBuilder().setName("_my_library").setFile("//:my_library.bzl")))
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("library_rules.my_plugin")
                    .setDocString("My language plugin")
                    .setOriginKey(
                        OriginKey.newBuilder().setName("_my_plugin").setFile("//:my_plugin.bzl")))
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("library_rules.my_import")
                    .setDocString("My language import")
                    .setOriginKey(
                        OriginKey.newBuilder().setName("_my_import").setFile("//:my_import.bzl")))
            .build();

    assertThat(collectModuleInfoDocsWithDenyList(moduleInfo, ImmutableSet.of("my_library")))
        .isEqualTo(2);

    assertThat(ruleDocEntries.keySet()).containsExactly("my_plugin", "my_import");
  }

  @Test
  public void collectModuleInfoDocs_expectsNonemptyModuleDocstring() throws Exception {
    BuildEncyclopediaDocException e =
        assertThrows(
            BuildEncyclopediaDocException.class,
            () -> collectModuleInfoDocs(ModuleInfo.newBuilder().setModuleDocstring("").build()));
    assertThat(e)
        .hasMessageThat()
        .contains("expected to be a single line representing a rule family name");
  }

  @Test
  public void collectModuleInfoDocs_multilineModuleDocstring() throws Exception {
    ModuleInfo moduleInfo =
        ModuleInfo.newBuilder()
            .setModuleDocstring("My Language\n\nBlah blah blah")
            .setFile("//:test.bzl")
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("library_rules.my_library")
                    .setDocString("My language library")
                    .setOriginKey(
                        OriginKey.newBuilder().setName("_my_library").setFile("//:my_library.bzl")))
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("library_rules.my_plugin")
                    .setDocString("My language plugin")
                    .setOriginKey(
                        OriginKey.newBuilder().setName("_my_plugin").setFile("//:my_plugin.bzl")))
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("test_rules.my_test")
                    .setDocString("My language test")
                    .setOriginKey(
                        OriginKey.newBuilder().setName("_my_test").setFile("//:my_test.bzl")))
            .build();

    assertThat(collectModuleInfoDocs(moduleInfo)).isEqualTo(3);

    // We expect family summary to be set only on the first rule, to avoid duplication in final
    // rendered output.
    assertThat(ruleDocEntries.get("my_library").getRuleFamily()).isEqualTo("My Language");
    assertThat(ruleDocEntries.get("my_library").getFamilySummary()).isEqualTo("Blah blah blah");
    assertThat(ruleDocEntries.get("my_plugin").getRuleFamily()).isEqualTo("My Language");
    assertThat(ruleDocEntries.get("my_plugin").getFamilySummary()).isEmpty();
    assertThat(ruleDocEntries.get("my_test").getRuleFamily()).isEqualTo("My Language");
    assertThat(ruleDocEntries.get("my_test").getFamilySummary()).isEmpty();
  }

  @Test
  public void collectModuleInfoDocs_linksCommonAttrsWithEmptyDocstringToCommonType()
      throws Exception {
    ModuleInfo moduleInfo =
        ModuleInfo.newBuilder()
            .setModuleDocstring("My Language")
            .setFile("//:test.bzl")
            .addRuleInfo(
                RuleInfo.newBuilder()
                    .setRuleName("library_rules.my_library")
                    .setDocString("My language library")
                    .setOriginKey(
                        OriginKey.newBuilder().setName("_my_library").setFile("//:my_library.bzl"))
                    .addAttribute(
                        AttributeInfo.newBuilder()
                            // Empty docstring
                            .setName("srcs")
                            .setType(AttributeType.LABEL_LIST)
                            .setDefaultValue("[]"))
                    .addAttribute(
                        AttributeInfo.newBuilder()
                            // Empty docstring
                            .setName("deps")
                            .setType(AttributeType.LABEL_LIST)
                            .setDefaultValue("[]"))
                    .addAttribute(
                        AttributeInfo.newBuilder()
                            // Empty docstring
                            .setName("uncommonly_named_attr")
                            .setType(AttributeType.LABEL_LIST)
                            .setDefaultValue("[]")))
            .build();

    assertThat(collectModuleInfoDocs(moduleInfo)).isEqualTo(1);

    Set<RuleDocumentationAttribute> attributes = ruleDocEntries.get("my_library").getAttributes();
    assertThat(getAttribute(attributes, "srcs").isCommonType()).isTrue();
    assertThat(getAttribute(attributes, "srcs").getGeneratedInRule("my_library"))
        .isEqualTo(DocgenConsts.TYPICAL_ATTRIBUTES);
    assertThat(getAttribute(attributes, "deps").isCommonType()).isTrue();
    assertThat(getAttribute(attributes, "deps").getGeneratedInRule("my_library"))
        .isEqualTo(DocgenConsts.TYPICAL_ATTRIBUTES);
    assertThat(getAttribute(attributes, "uncommonly_named_attr").isCommonType()).isFalse();
    assertThat(getAttribute(attributes, "uncommonly_named_attr").getGeneratedInRule("my_library"))
        .isEqualTo("my_library");
  }
}
