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

import com.google.common.collect.Interner;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.AbstractSkyKey;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyValue;

/**
 * A value that represents a local repository lookup result.
 *
 * <p>Local repository lookups will always produce a value. The {@code #getRepository} method
 * returns the name of the repository that the directory resides in.
 */
public abstract class LocalRepositoryLookupValue implements SkyValue {

  static Key key(RootedPath directory) {
    return Key.create(directory);
  }

  @AutoCodec.VisibleForSerialization
  @AutoCodec
  static class Key extends AbstractSkyKey<RootedPath> {
    private static final Interner<Key> interner = BlazeInterners.newWeakInterner();

    private Key(RootedPath arg) {
      super(arg);
    }

    @AutoCodec.VisibleForSerialization
    @AutoCodec.Instantiator
    static Key create(RootedPath arg) {
      return interner.intern(new Key(arg));
    }

    @Override
    public SkyFunctionName functionName() {
      return SkyFunctions.LOCAL_REPOSITORY_LOOKUP;
    }
  }

  private static final LocalRepositoryLookupValue MAIN_REPO_VALUE = new MainRepositoryLookupValue();
  private static final LocalRepositoryLookupValue NOT_FOUND_VALUE =
      new NotFoundLocalRepositoryLookupValue();

  public static LocalRepositoryLookupValue mainRepository() {
    return MAIN_REPO_VALUE;
  }

  public static LocalRepositoryLookupValue success(
      RepositoryName repositoryName, PathFragment path) {
    return new SuccessfulLocalRepositoryLookupValue(repositoryName, path);
  }

  public static LocalRepositoryLookupValue notFound() {
    return NOT_FOUND_VALUE;
  }

  /**
   * Returns {@code true} if the local repository lookup succeeded and the {@link #getRepository}
   * method will return a useful result.
   */
  public abstract boolean exists();

  /**
   * Returns the {@link RepositoryName} of the local repository contained in the directory which was
   * looked up, {@link RepositoryName#MAIN} if the directory is part of the main repository, or
   * throws a {@link IllegalStateException} if there was no repository found.
   */
  public abstract RepositoryName getRepository();

  /**
   * Returns the path to the local repository, or throws a {@link IllegalStateException} if there
   * was no repository found.
   */
  public abstract PathFragment getPath();

  /** Represents a successful lookup of the main repository. */
  public static final class MainRepositoryLookupValue extends LocalRepositoryLookupValue {

    // This should be a singleton value.
    private MainRepositoryLookupValue() {}

    @Override
    public boolean exists() {
      return true;
    }

    @Override
    public RepositoryName getRepository() {
      return RepositoryName.MAIN;
    }

    @Override
    public PathFragment getPath() {
      return PathFragment.EMPTY_FRAGMENT;
    }

    @Override
    public String toString() {
      return "MainRepositoryLookupValue";
    }

    @Override
    public boolean equals(Object obj) {
      // All MainRepositoryLookupValue instances are equivalent.
      return obj instanceof MainRepositoryLookupValue;
    }

    @Override
    public int hashCode() {
      return MainRepositoryLookupValue.class.getSimpleName().hashCode();
    }
  }

  /** Represents a successful lookup of a local repository. */
  public static final class SuccessfulLocalRepositoryLookupValue
      extends LocalRepositoryLookupValue {
    private final RepositoryName repositoryName;
    private final PathFragment path;

    public SuccessfulLocalRepositoryLookupValue(RepositoryName repositoryName, PathFragment path) {
      this.repositoryName = repositoryName;
      this.path = path;
    }

    @Override
    public boolean exists() {
      return true;
    }

    @Override
    public RepositoryName getRepository() {
      return repositoryName;
    }

    @Override
    public PathFragment getPath() {
      return path;
    }

    @Override
    public String toString() {
      return "SuccessfulLocalRepositoryLookupValue(" + repositoryName + ")";
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof SuccessfulLocalRepositoryLookupValue)) {
        return false;
      }
      SuccessfulLocalRepositoryLookupValue other = (SuccessfulLocalRepositoryLookupValue) obj;
      return repositoryName.equals(other.repositoryName);
    }

    @Override
    public int hashCode() {
      return repositoryName.hashCode();
    }
  }

  /** Represents the state where no repository was found, either local or the main repository. */
  public static final class NotFoundLocalRepositoryLookupValue extends LocalRepositoryLookupValue {

    // This should be a singleton value.
    private NotFoundLocalRepositoryLookupValue() {}

    @Override
    public boolean exists() {
      return false;
    }

    @Override
    public RepositoryName getRepository() {
      throw new IllegalStateException("Repository was not found");
    }

    @Override
    public PathFragment getPath() {
      throw new IllegalStateException("Repository was not found");
    }

    @Override
    public String toString() {
      return "NotFoundLocalRepositoryLookupValue";
    }

    @Override
    public boolean equals(Object obj) {
      // All NotFoundLocalRepositoryLookupValue instances are equivalent.
      return obj instanceof NotFoundLocalRepositoryLookupValue;
    }

    @Override
    public int hashCode() {
      return NotFoundLocalRepositoryLookupValue.class.getSimpleName().hashCode();
    }
  }
}
