// 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) {
    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) {

    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;
  }
}
