/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.model;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;

import java.io.File;

import javax.annotation.Nullable;

public final class BuildTarget implements Comparable<BuildTarget> {

  @VisibleForTesting
  public static final String BUILD_TARGET_PREFIX = "//";

  private final File buildFile;
  private final String baseName;
  private final String shortName;

  /**
   * Reserved for special internal targets such as {@link BuildTarget#ANDROID_SDK}, as well as
   * fake targets for testing.
   */
  @VisibleForTesting
  BuildTarget(String baseName, String shortName) {
    this(baseName, shortName, null /* buildFile */);
  }

  /**
   * Reserved for testing: normal constructor precondition checks are omitted.
   */
  @VisibleForTesting
  BuildTarget(String baseName, String shortName, File buildFile) {
    this.buildFile = buildFile;
    this.baseName = Preconditions.checkNotNull(baseName);
    this.shortName = Preconditions.checkNotNull(shortName);
  }

  public BuildTarget(File buildFile, String baseName, String shortName) {
    Preconditions.checkNotNull(buildFile);
    Preconditions.checkArgument(buildFile.isFile(), "%s must be a file", buildFile);
    this.buildFile = buildFile;

    Preconditions.checkNotNull(baseName);
    Preconditions.checkArgument(baseName.startsWith(BUILD_TARGET_PREFIX),
        "baseName must start with // but was %s",
        baseName);

    String parentDirectoryName = buildFile.getParentFile().getAbsolutePath();
    String basePath = baseName.substring(BUILD_TARGET_PREFIX.length());
    Preconditions.checkArgument(parentDirectoryName.endsWith(basePath),
        "file path %s did not end with %s for %s:%s", parentDirectoryName, basePath, baseName, shortName);
    this.baseName = baseName;

    this.shortName = Preconditions.checkNotNull(shortName);
  }

  /**
   * For use by InputRule, which is synthetic, and therefore has no buildFile.
   * @param inputFile Input file.
   * @param relativePath
   */
  private BuildTarget(File inputFile, String relativePath) {
    Preconditions.checkNotNull(inputFile);
    Preconditions.checkNotNull(relativePath);
    this.buildFile = null;
    this.baseName = String.format("//%s", relativePath);
    this.shortName = inputFile.getName();
  }

  /**
   * For exclusive use by {@link com.facebook.buck.rules.InputRule#InputRule(File, String)}.
   */
  public static BuildTarget createBuildTargetForInputFile(File inputFile, String relativePath) {
    return new BuildTarget(inputFile, relativePath);
  }

  /**
   * The build file in which this rule was defined.
   */
  @Nullable
  public File getBuildFile() {
    return buildFile;
  }

  /**
   * The directory that contains the corresponding build file.
   */
  public File getBuildFileDirectory() {
    return buildFile.getParentFile();
  }

  /**
   * If this build target were //third_party/java/guava:guava-latest, then this would return
   * "guava-latest".
   */
  public String getShortName() {
    return shortName;
  }

  /**
   * If this build target were //third_party/java/guava:guava-latest, then this would return
   * "//third_party/java/guava".
   */
  public String getBaseName() {
    return baseName;
  }

  /**
   * If this build target were //third_party/java/guava:guava-latest, then this would return
   * "//third_party/java/guava/".
   */
  public String getBaseNameWithSlash() {
    return getBaseNameWithSlash(baseName);
  }

  /**
   * Helper function for getting BuildTarget base names with a trailing slash if needed.
   *
   * If baseName were //third_party/java/guava, then this would return  "//third_party/java/guava/".
   * If it were //, it would return //.
   */
  @Nullable
  public static String getBaseNameWithSlash(@Nullable String baseName) {
    return baseName == null || baseName.equals(BUILD_TARGET_PREFIX) ? baseName : baseName + "/";
  }

  /**
   * If this build target were //third_party/java/guava:guava-latest, then this would return
   * "third_party/java/guava". This does not contain the "//" prefix so that it can be appended to
   * a file path.
   */
  public String getBasePath() {
    return baseName.substring(BUILD_TARGET_PREFIX.length());
  }

  /**
   * @return the value of {@link #getBasePath()} with a trailing slash, unless
   *     {@link #getBasePath()} returns the empty string, in which case this also returns the empty
   *     string
   */
  public String getBasePathWithSlash() {
    String basePath = getBasePath();
    return basePath.isEmpty() ? "" : basePath + "/";
  }

  /**
   * If this build target is //third_party/java/guava:guava-latest, then this would return
   * "//third_party/java/guava:guava-latest".
   */
  public String getFullyQualifiedName() {
    return String.format("%s:%s", baseName, shortName);
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof BuildTarget)) {
      return false;
    }
    BuildTarget that = (BuildTarget)o;
    return Objects.equal(this.buildFile, that.buildFile)
        && Objects.equal(this.baseName, that.baseName)
        && Objects.equal(this.shortName, that.shortName);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(buildFile, baseName, shortName);
  }

  /** @return {@link #getFullyQualifiedName()} */
  @Override
  public String toString() {
    return getFullyQualifiedName();
  }

  @Override
  public int compareTo(BuildTarget target) {
    Preconditions.checkNotNull(target);
    return getFullyQualifiedName().compareTo(target.getFullyQualifiedName());
  }
}
