/*
 * 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.rules;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetPattern;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;

import javax.annotation.Nullable;

/**
 * InputRule is a no-op BuildRule that encapsulates an input file. This encapsulation allows the
 * entire dependency graph to deal with BuildRules, rather than having leaves of a different type.
 */
public class InputRule implements BuildRule {

  private static final BuildRuleSuccess.Type SUCCESS_TYPE = BuildRuleSuccess.Type.BY_DEFINITION;

  private final File inputFile;
  private final BuildTarget buildTarget;
  private final ListenableFuture<BuildRuleSuccess> buildOutput;
  @Nullable private RuleKey ruleKey;

  /**
   * It is imperative that {@code inputFile} be properly relativized, so use
   * {@link #inputPathAsInputRule(String, Function)} to create an {@link InputRule}. The only reason
   * this method is {@code protected} rather than {@code private} is so that fakes can be created
   * for testing.
   */
  @VisibleForTesting
  protected InputRule(File inputFile, String relativePath) {
    this.inputFile = Preconditions.checkNotNull(inputFile);
    this.buildTarget = BuildTarget.createBuildTargetForInputFile(inputFile, relativePath);
    this.buildOutput = Futures.immediateFuture(new BuildRuleSuccess(this, SUCCESS_TYPE));
  }

  public static InputRule inputPathAsInputRule(String relativePath,
      Function<String, Path> pathRelativizer) {
    return Iterables.getOnlyElement(
        inputPathsAsInputRules(ImmutableList.of(relativePath), pathRelativizer));
  }

  /**
   * Convert a set of input file paths to InputRules.
   */
  public static ImmutableSortedSet<InputRule> inputPathsAsInputRules(Iterable<String> paths,
      Function<String, Path> pathRelativizer) {
    ImmutableSortedSet.Builder<InputRule> builder = ImmutableSortedSet.naturalOrder();
    for (String path : paths) {
      builder.add(new InputRule(pathRelativizer.apply(path).toFile(), path));
    }
    return builder.build();
  }

  @Override
  public BuildRuleSuccess.Type getBuildResultType() {
    return SUCCESS_TYPE;
  }

  @Nullable
  @Override
  public Buildable getBuildable() {
    return null;
  }

  @Override
  public BuildTarget getBuildTarget() {
    return buildTarget;
  }

  @Override
  public String getFullyQualifiedName() {
    return buildTarget.getFullyQualifiedName();
  }

  @Override
  public BuildRuleType getType() {
    return BuildRuleType.INPUT;
  }

  @Override
  public BuildableProperties getProperties() {
    return BuildableProperties.NONE;
  }

  @Override
  public ImmutableSortedSet<BuildRule> getDeps() {
    return ImmutableSortedSet.of();
  }

  @Override
  public ImmutableSet<BuildTargetPattern> getVisibilityPatterns() {
    return ImmutableSet.of(BuildTargetPattern.MATCH_ALL);
  }

  @Override
  public boolean isVisibleTo(BuildTarget target) {
    return true;
  }

  @Override
  public Iterable<InputRule> getInputs() {
    return ImmutableList.of();
  }

  @Override
  public ListenableFuture<BuildRuleSuccess> build(BuildContext context) {
    return buildOutput;
  }

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

  @Override
  public RuleKey getRuleKey() throws IOException {
    if (this.ruleKey == null) {
      ruleKey = RuleKey.builder(this).set("inputFile", inputFile).build().getTotalRuleKey();
    }
    return ruleKey;
  }

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

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (other == null || getClass() != other.getClass()) {
      return false;
    }
    return (compareTo((InputRule) other) == 0);
  }

  @Override
  public int compareTo(BuildRule buildRule) {
    return getFullyQualifiedName().compareTo(buildRule.getFullyQualifiedName());
  }

  @Override
  public String toString() {
    return getFullyQualifiedName();
  }

  @Override
  public RuleKey getRuleKeyWithoutDeps() throws IOException {
    throw new UnsupportedOperationException();
  }
}
