// Copyright 2021 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.cmdline;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import javax.annotation.Nullable;

/**
 * Stores the mapping from apparent repo name to canonical repo name, from the viewpoint of an
 * "owner repo".
 *
 * <p>For repositories from the WORKSPACE file, if the requested repo doesn't exist in the mapping,
 * we fallback to the requested name. For repositories from Bzlmod, we return null to let the caller
 * decide what to do.
 */
public class RepositoryMapping {
  /* A repo mapping that always falls back to using the apparent name as the canonical name. */
  public static final RepositoryMapping ALWAYS_FALLBACK = createAllowingFallback(ImmutableMap.of());

  private final ImmutableMap<String, RepositoryName> entries;
  @Nullable private final RepositoryName ownerRepo;

  private RepositoryMapping(
      Map<String, RepositoryName> entries, @Nullable RepositoryName ownerRepo) {
    this.entries = ImmutableMap.copyOf(entries);
    this.ownerRepo = ownerRepo;
  }

  /** Returns all the entries in this repo mapping. */
  public final ImmutableMap<String, RepositoryName> entries() {
    return entries;
  }

  /**
   * The owner repo of this repository mapping. It is for providing useful debug information when
   * repository mapping fails due to enforcing strict dependency, therefore it's only recorded when
   * we don't fall back to the requested repo name.
   */
  @Nullable
  public final RepositoryName ownerRepo() {
    return ownerRepo;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof RepositoryMapping)) {
      return false;
    }
    RepositoryMapping that = (RepositoryMapping) o;
    return Objects.equal(entries, that.entries) && Objects.equal(ownerRepo, that.ownerRepo);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(entries, ownerRepo);
  }

  public static RepositoryMapping create(
      Map<String, RepositoryName> entries, RepositoryName ownerRepo) {
    return new RepositoryMapping(
        Preconditions.checkNotNull(entries), Preconditions.checkNotNull(ownerRepo));
  }

  public static RepositoryMapping createAllowingFallback(Map<String, RepositoryName> entries) {
    return new RepositoryMapping(Preconditions.checkNotNull(entries), null);
  }

  /**
   * Create a new {@link RepositoryMapping} instance based on existing repo mappings and given
   * additional mappings. If there are conflicts, existing mappings will take precedence.
   */
  public RepositoryMapping withAdditionalMappings(Map<String, RepositoryName> additionalMappings) {
    HashMap<String, RepositoryName> allMappings = new HashMap<>(additionalMappings);
    allMappings.putAll(entries());
    return new RepositoryMapping(allMappings, ownerRepo());
  }

  /**
   * Create a new {@link RepositoryMapping} instance based on existing repo mappings and given
   * additional mappings. If there are conflicts, existing mappings will take precedence. The owner
   * repo of the given additional mappings is ignored.
   */
  public RepositoryMapping withAdditionalMappings(RepositoryMapping additionalMappings) {
    return withAdditionalMappings(additionalMappings.entries());
  }

  /**
   * Returns the canonical repository name associated with the given apparent repo name. The
   * provided apparent repo name is assumed to be valid.
   */
  public RepositoryName get(String preMappingName) {
    RepositoryName canonicalRepoName = entries().get(preMappingName);
    if (canonicalRepoName != null) {
      return canonicalRepoName;
    }
    // If the owner repo is not present, that means we should fall back to the requested repo name.
    if (ownerRepo() == null) {
      return RepositoryName.createUnvalidated(preMappingName);
    } else {
      return RepositoryName.createUnvalidated(preMappingName).toNonVisible(ownerRepo());
    }
  }

  /**
   * Whether the repo with this mapping is subject to strict deps; when strict deps is off, unknown
   * apparent names are silently treated as canonical names.
   */
  public boolean usesStrictDeps() {
    return ownerRepo() != null;
  }

  /**
   * Returns the first apparent name in this mapping that maps to the given canonical name, if any.
   */
  public Optional<String> getInverse(RepositoryName postMappingName) {
    return entries().entrySet().stream()
        .filter(e -> e.getValue().equals(postMappingName))
        .map(Entry::getKey)
        .findFirst();
  }

  /**
   * Creates a new {@link RepositoryMapping} instance that is the equivalent of composing this
   * {@link RepositoryMapping} with another one. That is, {@code a.composeWith(b).get(name) ===
   * b.get(a.get(name))} (treating {@code b} as allowing fallback).
   *
   * <p>Since we're treating the result of {@code a.get(name)} as an apparent repo name instead of a
   * canonical repo name, this only really makes sense when {@code a} does not use strict deps (i.e.
   * allows fallback).
   */
  public RepositoryMapping composeWith(RepositoryMapping other) {
    Preconditions.checkArgument(
        !usesStrictDeps(), "only an allow-fallback mapping can be composed with other mappings");
    HashMap<String, RepositoryName> entries = new HashMap<>(other.entries());
    for (Map.Entry<String, RepositoryName> entry : entries().entrySet()) {
      RepositoryName mappedName = other.get(entry.getValue().getName());
      entries.put(entry.getKey(), mappedName.isVisible() ? mappedName : entry.getValue());
    }
    return new RepositoryMapping(entries, null);
  }

  /**
   * Returns a new {@link RepositoryMapping} instance with identical contents, except that the
   * inverse mapping is cached, causing {@link #getInverse} to be much more efficient. This is
   * particularly important for the main repo mapping, as it's often used to generate display-form
   * labels ({@link Label#getDisplayForm}).
   */
  public RepositoryMapping withCachedInverseMap() {
    var inverse = Maps.<RepositoryName, String>newHashMapWithExpectedSize(entries.size());
    for (Map.Entry<String, RepositoryName> entry : entries.entrySet()) {
      inverse.putIfAbsent(entry.getValue(), entry.getKey());
    }
    var inverseCopy = ImmutableMap.copyOf(inverse);
    return new RepositoryMapping(entries, ownerRepo) {
      @Override
      public Optional<String> getInverse(RepositoryName postMappingName) {
        return Optional.ofNullable(inverseCopy.get(postMappingName));
      }
    };
  }
}
