// Copyright 2016 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.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.StringCanonicalizer;
import com.google.devtools.build.lib.util.StringUtilities;
import com.google.devtools.build.lib.vfs.OsPathPolicy;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;

/** A human-readable name for the repository. */
@AutoCodec
public final class RepositoryName implements Serializable {
  public static final String DEFAULT_REPOSITORY = "";
  @AutoCodec public static final RepositoryName DEFAULT;
  @AutoCodec public static final RepositoryName MAIN;
  private static final Pattern VALID_REPO_NAME = Pattern.compile("@[\\w\\-.]*");

  /** Helper for serializing {@link RepositoryName}. */
  private static final class SerializationProxy implements Serializable {
    private RepositoryName repositoryName;

    private SerializationProxy(RepositoryName repositoryName) {
      this.repositoryName = repositoryName;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
      out.writeObject(repositoryName.toString());
    }

    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException {
      try {
        repositoryName = RepositoryName.create((String) in.readObject());
      } catch (LabelSyntaxException e) {
        throw new IOException("Error serializing repository name: " + e.getMessage());
      }
    }

    @SuppressWarnings("unused")
    private void readObjectNoData() throws ObjectStreamException {
    }

    private Object readResolve() {
      return repositoryName;
    }
  }

  private void readObject(@SuppressWarnings("unused") ObjectInputStream in) throws IOException {
    throw new IOException("Serialization is allowed only by proxy");
  }

  private Object writeReplace() {
    return new SerializationProxy(this);
  }

  private static final LoadingCache<String, RepositoryName> repositoryNameCache =
      CacheBuilder.newBuilder()
        .weakValues()
        .build(
            new CacheLoader<String, RepositoryName>() {
              @Override
              public RepositoryName load(String name) throws LabelSyntaxException {
                String errorMessage = validate(name);
                if (errorMessage != null) {
                  errorMessage = "invalid repository name '"
                      + StringUtilities.sanitizeControlChars(name) + "': " + errorMessage;
                  throw new LabelSyntaxException(errorMessage);
                }
                return new RepositoryName(StringCanonicalizer.intern(name));
              }
            });

  static {
    try {
      DEFAULT = RepositoryName.create(RepositoryName.DEFAULT_REPOSITORY);
      MAIN = RepositoryName.create("@");
    } catch (LabelSyntaxException e) {
      throw new IllegalStateException(e);
    }
  }

  /**
   * Makes sure that name is a valid repository name and creates a new RepositoryName using it.
   *
   * @throws LabelSyntaxException if the name is invalid
   */
  @AutoCodec.Instantiator
  public static RepositoryName create(String name) throws LabelSyntaxException {
    try {
      return repositoryNameCache.get(name);
    } catch (ExecutionException e) {
      Throwables.propagateIfInstanceOf(e.getCause(), LabelSyntaxException.class);
      throw new IllegalStateException("Failed to create RepositoryName from " + name, e);
    }
  }

  /**
   * Creates a RepositoryName from a known-valid string (not @-prefixed). Generally this is a
   * directory that has been created via getSourceRoot() or getPathUnderExecRoot().
   */
  public static RepositoryName createFromValidStrippedName(String name) {
    try {
      return repositoryNameCache.get("@" + name);
    } catch (ExecutionException e) {
      throw new IllegalArgumentException(e.getMessage());
    }
  }

  /**
   * Extracts the repository name from a PathFragment that was created with {@code
   * PackageIdentifier.getSourceRoot}.
   *
   * @return a {@code Pair} of the extracted repository name and the path fragment with stripped of
   *     "external/"-prefix and repository name, or null if none was found or the repository name
   *     was invalid.
   */
  public static Pair<RepositoryName, PathFragment> fromPathFragment(
      PathFragment path, boolean siblingRepositoryLayout) {
    if (path.segmentCount() < 2) {
      return null;
    }

    PathFragment prefix =
        siblingRepositoryLayout
            ? LabelConstants.EXPERIMENTAL_EXTERNAL_PATH_PREFIX
            : LabelConstants.EXTERNAL_PATH_PREFIX;
    if (!path.startsWith(prefix)) {
      return null;
    }

    try {
      RepositoryName repoName = RepositoryName.create("@" + path.getSegment(1));
      PathFragment subPath = path.subFragment(2);
      return Pair.of(repoName, subPath);
    } catch (LabelSyntaxException e) {
      return null;
    }
  }

  private final String name;

  private RepositoryName(String name) {
    this.name = name;
  }

  /**
   * Performs validity checking.  Returns null on success, an error message otherwise.
   */
  static String validate(String name) {
    if (name.isEmpty()) {
      return null;
    }

    // Some special cases for more user-friendly error messages.
    if (!name.startsWith("@")) {
      return "workspace names must start with '@'";
    }
    if (name.equals("@.")) {
      return "workspace names are not allowed to be '@.'";
    }
    if (name.equals("@..")) {
      return "workspace names are not allowed to be '@..'";
    }

    if (!VALID_REPO_NAME.matcher(name).matches()) {
      return "workspace names may contain only A-Z, a-z, 0-9, '-', '_' and '.'";
    }

    return null;
  }

  /**
   * Returns the repository name without the leading "{@literal @}".  For the default repository,
   * returns "".
   */
  public String strippedName() {
    if (name.isEmpty()) {
      return name;
    }
    return name.substring(1);
  }

  /**
   * Returns the repository name without the leading "{@literal @}". For the default repository,
   * returns "".
   */
  public static String stripName(String repoName) {
    return repoName.startsWith("@") ? repoName.substring(1) : repoName;
  }

  /**
   * Returns if this is the default repository, that is, {@link #name} is "".
   */
  public boolean isDefault() {
    return name.isEmpty();
  }

  /**
   * Returns if this is the main repository, that is, {@link #name} is "@".
   */
  public boolean isMain() {
    return name.equals("@");
  }

  /**
   * Returns the repository name, with leading "{@literal @}" (or "" for the default repository).
   */
  // TODO(bazel-team): Use this over toString()- easier to track its usage.
  public String getName() {
    return name;
  }

  /**
   * Returns the repository name, except that the main repo is conflated with the default repo
   * ({@code "@"} becomes the empty string).
   */
  public String getDefaultCanonicalForm() {
    return isMain() ? "" : getName();
  }

  /**
   * Returns the relative path to the repository source. Returns "" for the main repository and
   * external/[repository name] for external repositories.
   */
  public PathFragment getSourceRoot() {
    return isDefault() || isMain()
        ? PathFragment.EMPTY_FRAGMENT
        : LabelConstants.EXTERNAL_PACKAGE_NAME.getRelative(strippedName());
  }

  /**
   * Returns the relative path to the repository's source for derived artifacts. This behavior is
   * currently the same for source artifacts, but we create a new method name to keep call sites
   * readable and not misleading.
   */
  public PathFragment getDerivedArtifactSourceRoot() {
    return getSourceRoot();
  }

  /**
   * Returns the runfiles/execRoot path for this repository. If we don't know the name of this repo
   * (i.e., it is in the main repository), return an empty path fragment.
   *
   * <p>If --experimental_sibling_repository_layout is true, return "$execroot/../repo" (sibling of
   * __main__), instead of "$execroot/external/repo".
   */
  public PathFragment getExecPath(boolean siblingRepositoryLayout) {
    if (isDefault() || isMain()) {
      return PathFragment.EMPTY_FRAGMENT;
    }
    PathFragment prefix =
        siblingRepositoryLayout
            ? LabelConstants.EXPERIMENTAL_EXTERNAL_PATH_PREFIX
            : LabelConstants.EXTERNAL_PATH_PREFIX;
    return prefix.getRelative(strippedName());
  }

  /**
   * Returns the runfiles path relative to the x.runfiles/main-repo directory.
   */
  // TODO(kchodorow): remove once execroot is reorg-ed.
  public PathFragment getRunfilesPath() {
    return isDefault() || isMain()
        ? PathFragment.EMPTY_FRAGMENT : PathFragment.create("..").getRelative(strippedName());
  }

  /**
   * Returns the repository name, with leading "{@literal @}" (or "" for the default repository).
   */
  @Override
  public String toString() {
    return name;
  }

  @Override
  public boolean equals(Object object) {
    if (this == object) {
      return true;
    }
    if (!(object instanceof RepositoryName)) {
      return false;
    }
    return OsPathPolicy.getFilePathOs().equals(name, ((RepositoryName) object).name);
  }

  @Override
  public int hashCode() {
    return OsPathPolicy.getFilePathOs().hash(name);
  }
}
