// 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 static com.google.devtools.build.lib.server.FailureDetails.TargetPatterns.Code.DEPENDENCY_NOT_FOUND;
import static com.google.devtools.common.options.OptionsParser.STARLARK_SKIPPED_PREFIXES;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.Label.PackageContext;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.runtime.StarlarkOptionsParser;
import com.google.devtools.build.lib.skyframe.PackageValue;
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 com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import javax.annotation.Nullable;

/**
 * Converts a list of command-line flags (like {@code --compilation_mode=dbg} or {@code
 * --//custom/starlark:flag=foo}) into a {@link NativeAndStarlarkFlags} instance. This is intended
 * as preparation for using the flags to create or update a build configuration in Bazel.
 */
public class ParsedFlagsFunction implements SkyFunction {
  private final ImmutableSet<Class<? extends FragmentOptions>> optionsClasses;

  public ParsedFlagsFunction(ImmutableSet<Class<? extends FragmentOptions>> optionsClasses) {
    this.optionsClasses = optionsClasses;
  }

  @Nullable
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws InterruptedException, ParsedFlagsFunctionException {
    ParsedFlagsValue.Key key = (ParsedFlagsValue.Key) skyKey.argument();

    ImmutableList.Builder<String> nativeFlags = ImmutableList.builder();
    ImmutableList.Builder<String> starlarkFlags = ImmutableList.builder();
    for (String flagSetting : key.rawFlags()) {
      if (STARLARK_SKIPPED_PREFIXES.stream().noneMatch(flagSetting::startsWith)) {
        nativeFlags.add(flagSetting);
      } else {
        starlarkFlags.add(flagSetting);
      }
    }
    // The StarlarkOptionsParser needs a native options parser just to inject its Starlark flag
    // values. It doesn't actually parse anything with the native parser.
    OptionsParser fakeNativeParser = OptionsParser.builder().build();
    StarlarkOptionsParser starlarkFlagParser =
        StarlarkOptionsParser.newStarlarkOptionsParser(
            new SkyframeTargetLoader(env, key.packageContext()), fakeNativeParser);
    try {
      if (!starlarkFlagParser.parseGivenArgs(starlarkFlags.build())) {
        return null;
      }
    } catch (OptionsParsingException e) {
      throw new ParsedFlagsFunctionException(e);
    }
    NativeAndStarlarkFlags flags =
        NativeAndStarlarkFlags.builder()
            .nativeFlags(nativeFlags.build())
            .starlarkFlags(fakeNativeParser.getStarlarkOptions())
            .optionsClasses(optionsClasses)
            .repoMapping(key.packageContext().repoMapping())
            .build();

    return ParsedFlagsValue.create(flags);
  }

  /**
   * Lets {@link StarlarkOptionsParser} convert flag names to {@link Target}s through a Skyframe
   * {@link PackageValue} lookup.
   */
  private static class SkyframeTargetLoader implements StarlarkOptionsParser.BuildSettingLoader {
    private final Environment env;
    private final PackageContext packageContext;

    public SkyframeTargetLoader(Environment env, PackageContext packageContext) {
      this.env = env;
      this.packageContext = packageContext;
    }

    @Nullable
    @Override
    public Target loadBuildSetting(String name)
        throws InterruptedException, TargetParsingException {
      Label asLabel;
      try {
        asLabel = Label.parseWithPackageContext(name, packageContext);
      } catch (LabelSyntaxException e) {
        throw new IllegalArgumentException(e);
      }
      try {
        SkyKey pkgKey = asLabel.getPackageIdentifier();
        PackageValue pkg = (PackageValue) env.getValueOrThrow(pkgKey, NoSuchPackageException.class);
        if (pkg == null) {
          return null;
        }
        return pkg.getPackage().getTarget(asLabel.getName());
      } catch (NoSuchPackageException | NoSuchTargetException e) {
        throw new TargetParsingException(
            String.format("Failed to load %s", name), e, DEPENDENCY_NOT_FOUND);
      }
    }
  }

  /** Exception class for errors during flag parsing. */
  public static class ParsedFlagsFunctionException extends SkyFunctionException {
    ParsedFlagsFunctionException(OptionsParsingException e) {
      super(e, Transience.PERSISTENT);
    }
  }
}
