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

import com.google.auto.value.AutoValue;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Comparator;
import java.util.List;

/** A module name, version pair that identifies a module in the external dependency graph. */
@AutoValue
public abstract class ModuleKey {

  /**
   * A mapping from module name to repository name for certain special "well-known" modules.
   *
   * <p>The repository name of certain modules are required to be exact strings (instead of the
   * normal format seen in {@link #getCanonicalRepoName()}) due to backwards compatibility reasons.
   * For example, bazel_tools must be known as "@bazel_tools" for WORKSPACE repos to work correctly.
   */
  private static final ImmutableMap<String, RepositoryName> WELL_KNOWN_MODULES =
      ImmutableMap.of(
          "bazel_tools",
          RepositoryName.BAZEL_TOOLS,
          "local_config_platform",
          RepositoryName.createUnvalidated("local_config_platform"),
          // Ensures that references to "@platforms" in WORKSPACE files resolve to the repository of
          // the "platforms" module. Without this, constraints on toolchains registered in WORKSPACE
          // would reference the "platforms" repository defined in the WORKSPACE suffix, whereas
          // the host constraints generated by local_config_platform would reference the "platforms"
          // module repository, resulting in a toolchain resolution mismatch.
          "platforms",
          RepositoryName.createUnvalidated("platforms"));

  public static final ModuleKey ROOT = create("", Version.EMPTY);

  public static final Comparator<ModuleKey> LEXICOGRAPHIC_COMPARATOR =
      Comparator.comparing(ModuleKey::getName).thenComparing(ModuleKey::getVersion);

  public static ModuleKey create(String name, Version version) {
    return new AutoValue_ModuleKey(name, version);
  }

  /** The name of the module. Must be empty for the root module. */
  public abstract String getName();

  /** The version of the module. Must be empty iff the module has a {@link NonRegistryOverride}. */
  public abstract Version getVersion();

  /** Returns the label that points to the MODULE.bazel file of this module. */
  public final Label moduleFileLabel() {
    return Label.createUnvalidated(
        PackageIdentifier.create(getCanonicalRepoName(), PathFragment.EMPTY_FRAGMENT),
        LabelConstants.MODULE_DOT_BAZEL_FILE_NAME.getBaseName());
  }

  @Override
  public final String toString() {
    if (this.equals(ROOT)) {
      return "<root>";
    }
    return getName() + "@" + (getVersion().isEmpty() ? "_" : getVersion().toString());
  }

  /** Returns the canonical name of the repo backing this module. */
  public RepositoryName getCanonicalRepoName() {
    if (WELL_KNOWN_MODULES.containsKey(getName())) {
      return WELL_KNOWN_MODULES.get(getName());
    }
    if (ROOT.equals(this)) {
      return RepositoryName.MAIN;
    }
    return RepositoryName.createUnvalidated(
        String.format("%s~%s", getName(), getVersion().isEmpty() ? "override" : getVersion()));
  }

  public static ModuleKey fromString(String s) throws Version.ParseException {
    if (s.equals("<root>")) {
      return ModuleKey.ROOT;
    }
    List<String> parts = Splitter.on('@').splitToList(s);
    if (parts.get(1).equals("_")) {
      return ModuleKey.create(parts.get(0), Version.EMPTY);
    }

    Version version = Version.parse(parts.get(1));
    return ModuleKey.create(parts.get(0), version);
  }
}
