// Copyright 2022 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.bazel.bzlmod.modcommand;

import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.bazel.bzlmod.BazelModuleInspectorValue.AugmentedModule;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleExtensionId;
import com.google.devtools.build.lib.bazel.bzlmod.ModuleKey;
import com.google.devtools.build.lib.bazel.bzlmod.Version;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModExecutor.ResultNode;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModExecutor.ResultNode.IsCycle;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModExecutor.ResultNode.IsExpanded;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModExecutor.ResultNode.IsIndirect;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModExecutor.ResultNode.NodeMetadata;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModOptions.Charset;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.ModOptions.ExtensionShow;
import com.google.devtools.build.lib.bazel.bzlmod.modcommand.OutputFormatters.OutputFormatter;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;

/** Outputs graph-based results of {@link ModExecutor} in a human-readable text format. */
public class TextOutputFormatter extends OutputFormatter {

  private Deque<Boolean> isLastChildStack;
  private DrawCharset drawCharset;
  private Set<ModuleExtensionId> seenExtensions;
  private StringBuilder str;

  @Override
  public void output() {
    if (options.charset == Charset.ASCII) {
      drawCharset = DrawCharset.ASCII;
    } else {
      drawCharset = DrawCharset.UTF8;
    }
    isLastChildStack = new ArrayDeque<>();
    seenExtensions = new HashSet<>();
    str = new StringBuilder();
    printModule(ModuleKey.ROOT, null, IsExpanded.TRUE, IsIndirect.FALSE, IsCycle.FALSE, 0);
    this.printer.println(str);
  }

  // Prints the indents and the tree drawing characters.
  private void printTreeDrawing(IsIndirect indirect, int depth) {
    if (depth > 0) {
      int indents = isLastChildStack.size() - 1;
      Iterator<Boolean> value = isLastChildStack.descendingIterator();
      for (int i = 0; i < indents; i++) {
        boolean isLastChild = value.next();
        if (isLastChild) {
          str.append(drawCharset.emptyIndent);
        } else {
          str.append(drawCharset.prevChildIndent);
        }
      }
      if (indirect == IsIndirect.TRUE) {
        if (isLastChildStack.getFirst()) {
          str.append(drawCharset.lastIndirectChildIndent);
        } else {
          str.append(drawCharset.indirectChildIndent);
        }
      } else {
        if (isLastChildStack.getFirst()) {
          str.append(drawCharset.lastChildIndent);

        } else {
          str.append(drawCharset.childIndent);
        }
      }
    }
  }

  // Helper to print module extensions similarly to printModule.
  private void printExtension(
      ModuleKey key, ModuleExtensionId extensionId, boolean unexpanded, int depth) {
    printTreeDrawing(IsIndirect.FALSE, depth);
    str.append('$');
    str.append(extensionId.asTargetString());
    str.append(' ');
    if (unexpanded && options.extensionInfo == ExtensionShow.ALL) {
      str.append("... ");
    }
    str.append("\n");
    if (options.extensionInfo == ExtensionShow.USAGES) {
      return;
    }
    ImmutableSortedSet<String> repoImports =
        ImmutableSortedSet.copyOf(extensionRepoImports.get(extensionId).inverse().get(key));
    ImmutableSortedSet<String> unusedRepos = ImmutableSortedSet.of();
    if (!unexpanded && options.extensionInfo == ExtensionShow.ALL) {
      unusedRepos =
          ImmutableSortedSet.copyOf(
              Sets.difference(
                  extensionRepos.get(extensionId), extensionRepoImports.get(extensionId).keySet()));
    }
    int totalChildrenNum = repoImports.size() + unusedRepos.size();
    int currChild = 1;
    for (String usedRepo : repoImports) {
      isLastChildStack.push(currChild++ == totalChildrenNum);
      printExtensionRepo(usedRepo, IsIndirect.FALSE, depth + 1);
      isLastChildStack.pop();
    }
    if (unexpanded || options.extensionInfo == ExtensionShow.REPOS) {
      return;
    }
    for (String unusedPackage : unusedRepos) {
      isLastChildStack.push(currChild++ == totalChildrenNum);
      printExtensionRepo(unusedPackage, IsIndirect.TRUE, depth + 1);
      isLastChildStack.pop();
    }
  }

  // Prints an extension repo line.
  private void printExtensionRepo(String repoName, IsIndirect indirectLink, int depth) {
    printTreeDrawing(indirectLink, depth);
    str.append(repoName).append("\n");
  }

  // Depth-first traversal to print the actual output
  private void printModule(
      ModuleKey key,
      ModuleKey parent,
      IsExpanded expanded,
      IsIndirect indirect,
      IsCycle cycle,
      int depth) {
    printTreeDrawing(indirect, depth);

    ResultNode node = Objects.requireNonNull(result.get(key));
    if (key.equals(ModuleKey.ROOT)) {
      AugmentedModule rootModule = depGraph.get(ModuleKey.ROOT);
      Preconditions.checkNotNull(rootModule);
      str.append(
          String.format(
              "<root> (%s@%s)",
              rootModule.getName(),
              rootModule.getVersion().equals(Version.EMPTY) ? "_" : rootModule.getVersion()));
    } else {
      str.append(key).append(" ");
    }

    int totalChildrenNum = node.getChildren().size();

    ImmutableSortedSet<ModuleExtensionId> extensionsUsed =
        extensionRepoImports.keySet().stream()
            .filter(e -> extensionRepoImports.get(e).inverse().containsKey(key))
            .collect(toImmutableSortedSet(ModuleExtensionId.LEXICOGRAPHIC_COMPARATOR));
    if (options.extensionInfo != ExtensionShow.HIDDEN) {
      totalChildrenNum += extensionsUsed.size();
    }

    if (cycle == IsCycle.TRUE) {
      str.append("(cycle) ");
    } else if (expanded == IsExpanded.FALSE) {
      str.append("(*) ");
    } else {
      if (totalChildrenNum != 0 && node.isTarget()) {
        str.append("# ");
      }
    }
    AugmentedModule module = Objects.requireNonNull(depGraph.get(key));
    if (!options.verbose && !module.isUsed()) {
      str.append("(unused) ");
    }
    // If the edge is indirect, the parent is not only unknown, but the node could have come
    // from multiple paths merged in the process, so we skip the resolution explanation.
    if (indirect == IsIndirect.FALSE && options.verbose && parent != null) {
      Explanation explanation = getExtraResolutionExplanation(key, parent);
      if (explanation != null) {
        str.append(explanation.toExplanationString(!module.isUsed()));
      }
    }

    str.append("\n");

    if (expanded == IsExpanded.FALSE) {
      return;
    }

    int currChild = 1;
    if (options.extensionInfo != ExtensionShow.HIDDEN) {
      for (ModuleExtensionId extensionId : extensionsUsed) {
        boolean unexpandedExtension = !seenExtensions.add(extensionId);
        isLastChildStack.push(currChild++ == totalChildrenNum);
        printExtension(key, extensionId, unexpandedExtension, depth + 1);
        isLastChildStack.pop();
      }
    }
    for (Entry<ModuleKey, NodeMetadata> e : node.getChildrenSortedByEdgeType()) {
      ModuleKey childKey = e.getKey();
      IsExpanded childExpanded = e.getValue().isExpanded();
      IsIndirect childIndirect = e.getValue().isIndirect();
      IsCycle childCycles = e.getValue().isCycle();
      isLastChildStack.push(currChild++ == totalChildrenNum);
      printModule(childKey, key, childExpanded, childIndirect, childCycles, depth + 1);
      isLastChildStack.pop();
    }
  }

  enum DrawCharset {
    ASCII("    ", "|   ", "|___", "|...", "|___", "|..."),
    UTF8("    ", "│   ", "├───", "├╌╌╌", "└───", "└╌╌╌");
    final String emptyIndent;
    final String prevChildIndent;
    final String childIndent;
    final String indirectChildIndent;
    final String lastChildIndent;
    final String lastIndirectChildIndent;

    DrawCharset(
        String emptyIndent,
        String prevChildIndent,
        String childIndent,
        String indirectChildIndent,
        String lastChildIndent,
        String lastIndirectChildIndent) {
      this.emptyIndent = emptyIndent;
      this.prevChildIndent = prevChildIndent;
      this.childIndent = childIndent;
      this.indirectChildIndent = indirectChildIndent;
      this.lastChildIndent = lastChildIndent;
      this.lastIndirectChildIndent = lastIndirectChildIndent;
    }
  }
}
