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

import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.util.Comparator.comparing;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.DeterministicWriter;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.util.Fingerprint;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;

/** Creates a manifest file describing the repos and mappings relevant for a runfile tree. */
public class RepoMappingManifestAction extends AbstractFileWriteAction {
  private static final UUID MY_UUID = UUID.fromString("458e351c-4d30-433d-b927-da6cddd4737f");

  private final ImmutableList<Entry> entries;
  private final String workspaceName;

  /** An entry in the repo mapping manifest file. */
  @AutoValue
  public abstract static class Entry {
    public static Entry of(
        RepositoryName sourceRepo, String targetRepoApparentName, RepositoryName targetRepo) {
      return new AutoValue_RepoMappingManifestAction_Entry(
          sourceRepo, targetRepoApparentName, targetRepo);
    }

    public abstract RepositoryName sourceRepo();

    public abstract String targetRepoApparentName();

    public abstract RepositoryName targetRepo();
  }

  public RepoMappingManifestAction(
      ActionOwner owner, Artifact output, List<Entry> entries, String workspaceName) {
    super(owner, NestedSetBuilder.emptySet(Order.STABLE_ORDER), output, /*makeExecutable=*/ false);
    this.entries =
        ImmutableList.sortedCopyOf(
            comparing((Entry e) -> e.sourceRepo().getName())
                .thenComparing(Entry::targetRepoApparentName),
            entries);
    this.workspaceName = workspaceName;
  }

  @Override
  public String getMnemonic() {
    return "RepoMappingManifest";
  }

  @Override
  protected String getRawProgressMessage() {
    return "writing repo mapping manifest for " + getOwner().getLabel();
  }

  @Override
  protected void computeKey(
      ActionKeyContext actionKeyContext,
      @Nullable ArtifactExpander artifactExpander,
      Fingerprint fp)
      throws CommandLineExpansionException, EvalException, InterruptedException {
    fp.addUUID(MY_UUID);
    fp.addString(workspaceName);
    for (Entry entry : entries) {
      fp.addString(entry.sourceRepo().getName());
      fp.addString(entry.targetRepoApparentName());
      fp.addString(entry.targetRepo().getName());
    }
  }

  @Override
  public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx)
      throws InterruptedException, ExecException {
    return out -> {
      PrintWriter writer = new PrintWriter(out, /*autoFlush=*/ false, ISO_8859_1);
      for (Entry entry : entries) {
        if (entry.targetRepoApparentName().isEmpty()) {
          // The apparent repo name can only be empty for the main repo. We skip this line as
          // Rlocation paths can't reference an empty apparent name anyway.
          Preconditions.checkArgument(
              entry.sourceRepo().isMain(),
              "only the main repo mapping can contain an entry with an empty apparent name");
          continue;
        }
        // The canonical name of the main repo is the empty string, which is not a valid name for a
        // directory, so the "workspace name" is used the name of the directory under the runfiles
        // tree for it.
        String targetRepoDirectoryName =
            entry.targetRepo().isMain() ? workspaceName : entry.targetRepo().getName();
        writer.format(
            "%s,%s,%s\n",
            entry.sourceRepo().getName(), entry.targetRepoApparentName(), targetRepoDirectoryName);
      }
      writer.flush();
    };
  }
}
