// Copyright 2014 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.FileValue;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.skyframe.PackageLookupValue;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nullable;

/**
 * A {@link SkyFunction} that does things for FDO that a regular configured target is not allowed
 * to.
 *
 * <p>This only exists because the value of {@code --fdo_optimize} can be a workspace-relative path
 * and thus we need to depend on {@link BlazeDirectories} somehow, which neither the configuration
 * nor the analysis phase can "officially" do.
 *
 * <p>The fix is probably to make it possible for {@link
 * com.google.devtools.build.lib.analysis.actions.SymlinkAction} to create workspace-relative
 * symlinks because action execution can hopefully depend on {@link BlazeDirectories}.
 *
 * <p>There is also the awful and incorrect {@link Path#exists()} call in {@link
 * com.google.devtools.build.lib.view.proto.CcProtoProfileProvider#getProfile(
 * com.google.devtools.build.lib.analysis.RuleContext)} which needs a {@link Path}.
 */
public class CcSkyframeSupportFunction implements SkyFunction {

  private final BlazeDirectories directories;

  public CcSkyframeSupportFunction(BlazeDirectories directories) {
    this.directories = Preconditions.checkNotNull(directories);
  }

  @Nullable
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws InterruptedException, CcSkyframeSupportException {
    CcSkyframeSupportValue.Key key = (CcSkyframeSupportValue.Key) skyKey.argument();
    Path fdoZipPath = null;
    if (key.getFdoZipPath() != null) {
      fdoZipPath = directories.getWorkspace().getRelative(key.getFdoZipPath());
    }

    CrosstoolRelease crosstoolRelease = null;
    if (key.getCcToolchainSuiteLabel() != null) {
      try {
        // 1. Lookup the package to handle multiple package roots (PackageLookupValue)
        PackageIdentifier packageIdentifier = key.getCcToolchainSuiteLabel().getPackageIdentifier();
        PackageLookupValue crosstoolPackageValue =
            (PackageLookupValue) env.getValue(PackageLookupValue.key(packageIdentifier));
        if (env.valuesMissing()) {
          return null;
        }

        // 2. Get crosstool file (FileValue)
        PathFragment crosstool =
            packageIdentifier
                .getPackageFragment()
                .getRelative(CrosstoolConfigurationLoader.CROSSTOOL_CONFIGURATION_FILENAME);
        FileValue crosstoolFileValue =
            (FileValue)
                env.getValue(
                    FileValue.key(
                        RootedPath.toRootedPath(crosstoolPackageValue.getRoot(), crosstool)));
        if (env.valuesMissing()) {
          return null;
        }

        // 3. Parse the crosstool file the into CrosstoolRelease
        Path crosstoolFile = crosstoolFileValue.realRootedPath().asPath();
        try (InputStream inputStream = crosstoolFile.getInputStream()) {
          String crosstoolContent = new String(FileSystemUtils.readContentAsLatin1(inputStream));
          crosstoolRelease =
              CrosstoolConfigurationLoader.toReleaseConfiguration(
                  "CROSSTOOL file " + crosstool, () -> crosstoolContent, /* digestOrNull= */ null);
        }
      } catch (IOException | InvalidConfigurationException e) {
        throw new CcSkyframeSupportException(e, key);
      }
    }

    return new CcSkyframeSupportValue(fdoZipPath, crosstoolRelease);
  }

  @Nullable
  @Override
  public String extractTag(SkyKey skyKey) {
    return null;
  }

  /** Exception encapsulating IOExceptions thrown in {@link CcSkyframeSupportFunction} */
  public static class CcSkyframeSupportException extends SkyFunctionException {

    public CcSkyframeSupportException(Exception cause, SkyKey childKey) {
      super(cause, childKey);
    }
  }
}
