// Copyright 2024 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.skyframe.config;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.BuildOptionsView;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.Label.RepoContext;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.skyframe.BzlLoadFailedException;
import com.google.devtools.build.lib.skyframe.BzlLoadValue;
import com.google.devtools.build.lib.skyframe.RepositoryMappingValue;
import com.google.devtools.build.lib.skyframe.config.ParsedFlagsFunction.ParsedFlagsFunctionException;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.OptionsParsingResult;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;

/**
 * A SkyFunction that, given an scl file path and the name of scl configs, does the following: 1)
 * call {@link BzlLoadFunction} to load the content of scl files given the provided scl config name
 * 2) call {@link ParsedFlagsFunction} to parse the list of options 3) define a patch transition and
 * applies the transition to the targetOptions which was used for creating topLevel configuration.
 *
 * <p>If given an unknown {@link CoreOptions.sclConfig}, {@link FlagSetFunction} will return the
 * original {@link BuildOptions} and will not error out.
 */
public class FlagSetFunction implements SkyFunction {

  @Override
  @SuppressWarnings("unchecked")
  @Nullable
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws FlagSetFunctionException, ParsedFlagsFunctionException, InterruptedException {
    FlagSetValue.Key key = (FlagSetValue.Key) skyKey.argument();

    if (key.getProjectFile() == null || key.getSclConfig().isEmpty()) {
      return FlagSetValue.create(key.getTargetOptions());
    }

    String parentDirectoryString = key.getProjectFile().getParentDirectory().getPathString();
    String baseName = key.getProjectFile().getBaseName();
    String projectFileLabelString = parentDirectoryString + ":" + baseName;

    BzlLoadValue sclLoadValue = loadSclFile(projectFileLabelString, env);

    if (sclLoadValue == null) {
      return null;
    }

    RepositoryMappingValue mainRepositoryMappingValue =
        (RepositoryMappingValue) env.getValue(RepositoryMappingValue.key(RepositoryName.MAIN));
    if (mainRepositoryMappingValue == null) {
      return null;
    }

    RepoContext mainRepoContext =
        RepoContext.of(RepositoryName.MAIN, mainRepositoryMappingValue.getRepositoryMapping());

    List<String> rawFlags = new ArrayList<>();
    if (sclLoadValue.getModule().getGlobal(key.getSclConfig()) != null) {
      rawFlags.addAll(
          (Collection<? extends String>) sclLoadValue.getModule().getGlobal(key.getSclConfig()));
    } else {
      return FlagSetValue.create(key.getTargetOptions());
    }

    ParsedFlagsValue parsedFlagsValue;
    try {
      parsedFlagsValue =
          (ParsedFlagsValue)
              env.getValueOrThrow(
                  ParsedFlagsValue.Key.create(
                      ImmutableList.copyOf(rawFlags), mainRepoContext.rootPackage()),
                  ParsedFlagsFunctionException.class);
    } catch (ParsedFlagsFunctionException e) {
      throw new FlagSetFunctionException(e, Transience.PERSISTENT);
    }

    if (parsedFlagsValue == null) {
      return null;
    }

    BuildOptions adjustedBuildOptions;
    try {
      OptionsParsingResult optionsParsingResult = parsedFlagsValue.flags().parse();
      FlagSetTransition transition = new FlagSetTransition(optionsParsingResult);
      BuildOptionsView buildOptionsView =
          new BuildOptionsView(key.getTargetOptions(), parsedFlagsValue.flags().optionsClasses());
      adjustedBuildOptions =
          Iterables.getOnlyElement(transition.apply(buildOptionsView, env.getListener()).values());
    } catch (OptionsParsingException e) {
      throw new FlagSetFunctionException(e, Transience.PERSISTENT);
    }

    return FlagSetValue.create(adjustedBuildOptions);
  }

  private BzlLoadValue loadSclFile(String sclFile, Environment env)
      throws FlagSetFunctionException, InterruptedException {
    BzlLoadValue bzlLoadValue;
    try {
      Label sclFileLabel = Label.parseCanonical(sclFile);
      bzlLoadValue =
          (BzlLoadValue)
              env.getValueOrThrow(
                  BzlLoadValue.keyForBuild(sclFileLabel), BzlLoadFailedException.class);
    } catch (BzlLoadFailedException | LabelSyntaxException e) {
      throw new FlagSetFunctionException(e, Transience.PERSISTENT);
    }
    return bzlLoadValue;
  }

  private static final class FlagSetFunctionException extends SkyFunctionException {
    FlagSetFunctionException(Exception cause, Transience transience) {
      super(cause, transience);
    }
  }

  /** Transition that applies the config defines in PROJECT.scl to existing buildOptions */
  private static class FlagSetTransition implements PatchTransition {
    public final OptionsParsingResult parsingResult;

    public FlagSetTransition(OptionsParsingResult parsingResult) {
      this.parsingResult = parsingResult;
    }

    @Override
    public BuildOptions patch(BuildOptionsView originalOptions, EventHandler eventHandler) {
      BuildOptions toOptions = originalOptions.underlying().clone();
      return toOptions.applyParsingResult(parsingResult);
    }
  }
}
