// Copyright 2020 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.rules.cpp;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.FileType.HasFileType;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Objects;
import javax.annotation.Nullable;

/** Value object reused by propeller configurations that has two artifacts. */
@Immutable
public final class PropellerOptimizeInputFile implements HasFileType {

  private final Artifact ccArtifact;
  private final Artifact ldArtifact;

  public PropellerOptimizeInputFile(Artifact ccArtifact, Artifact ldArtifact) {
    Preconditions.checkArgument((ccArtifact != null) || (ldArtifact != null));
    this.ccArtifact = ccArtifact;
    this.ldArtifact = ldArtifact;
  }

  public Artifact getCcArtifact() {
    return ccArtifact;
  }

  public Artifact getLdArtifact() {
    return ldArtifact;
  }

  public String getBasename() {
    return ccArtifact != null ? ccArtifact.getFilename() : ldArtifact.getFilename();
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }

    if (!(o instanceof PropellerOptimizeInputFile)) {
      return false;
    }

    PropellerOptimizeInputFile that = (PropellerOptimizeInputFile) o;
    return Objects.equals(this.ccArtifact, that.ccArtifact)
        && Objects.equals(this.ldArtifact, that.ldArtifact);
  }

  @Override
  public int hashCode() {
    return Objects.hash(ccArtifact, ldArtifact);
  }

  public static Artifact createAbsoluteArtifact(
      RuleContext ruleContext, PathFragment absolutePath) {
    Artifact artifact =
        ruleContext.getUniqueDirectoryArtifact(
            "fdo", absolutePath.getBaseName(), ruleContext.getBinOrGenfilesDirectory());
    ruleContext.registerAction(
        SymlinkAction.toAbsolutePath(
            ruleContext.getActionOwner(),
            PathFragment.create(absolutePath.getPathString()),
            artifact,
            "Symlinking LLVM Propeller Profile " + absolutePath.getPathString()));
    return artifact;
  }

  @Nullable
  public static Artifact getAbsolutePathArtifact(RuleContext ruleContext, String attributeName)
      throws InterruptedException {
    String pathString = ruleContext.getExpander().expand(attributeName);
    PathFragment absolutePath = PathFragment.create(pathString);
    if (!ruleContext.getFragment(CppConfiguration.class).isFdoAbsolutePathEnabled()) {
      ruleContext.ruleError(
          "absolute paths cannot be used when --enable_fdo_profile_absolute_path is false");
      return null;
    }
    if (!absolutePath.isAbsolute()) {
      ruleContext.attributeError(
          attributeName, String.format("%s is not an absolute path", absolutePath.getPathString()));
      return null;
    }
    return createAbsoluteArtifact(ruleContext, absolutePath);
  }

  @Nullable
  public static PropellerOptimizeInputFile fromProfileRule(RuleContext ruleContext)
      throws InterruptedException {

    boolean isCcProfile =
        ruleContext.attributes().isAttributeValueExplicitlySpecified("cc_profile");
    boolean isAbsCcProfile =
        ruleContext.attributes().isAttributeValueExplicitlySpecified("absolute_cc_profile");
    boolean isLdProfile =
        ruleContext.attributes().isAttributeValueExplicitlySpecified("ld_profile");
    boolean isAbsLdProfile =
        ruleContext.attributes().isAttributeValueExplicitlySpecified("absolute_ld_profile");

    if (!isCcProfile && !isLdProfile && !isAbsCcProfile && !isAbsLdProfile) {
      return null;
    }

    if (isCcProfile && isAbsCcProfile) {
      ruleContext.attributeError("cc_profile", "Both relative and absolute profiles are provided.");
    }

    if (isLdProfile && isAbsLdProfile) {
      ruleContext.attributeError("ld_profile", "Both relative and absolute profiles are provided.");
    }

    Artifact ccArtifact = null;
    if (isCcProfile) {
      ccArtifact = ruleContext.getPrerequisiteArtifact("cc_profile");
      if (!ccArtifact.isSourceArtifact()) {
        ruleContext.attributeError("cc_profile", "the target is not an input file");
      }
    } else if (isAbsCcProfile) {
      ccArtifact = getAbsolutePathArtifact(ruleContext, "absolute_cc_profile");
    }

    Artifact ldArtifact = null;
    if (isLdProfile) {
      ldArtifact = ruleContext.getPrerequisiteArtifact("ld_profile");
      if (!ldArtifact.isSourceArtifact()) {
        ruleContext.attributeError("ld_profile", "the target is not an input file");
      }
    } else if (isAbsLdProfile) {
      ldArtifact = getAbsolutePathArtifact(ruleContext, "absolute_ld_profile");
    }
    if (ccArtifact != null || ldArtifact != null) {
      return new PropellerOptimizeInputFile(ccArtifact, ldArtifact);
    } else {
      return null;
    }
  }

  @Override
  public String filePathForFileTypeMatcher() {
    String s = "";
    if (ccArtifact != null) {
      s += ccArtifact.filePathForFileTypeMatcher();
    }
    if (ldArtifact != null) {
      s += ldArtifact.filePathForFileTypeMatcher();
    }
    return s;
  }
}
