// Copyright 2023 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.analysis.config;

import com.google.auto.value.AutoValue;
import com.google.common.base.Splitter;
import com.google.common.base.Verify;
import com.google.devtools.build.lib.analysis.starlark.StarlarkAttributeTransitionProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.skyframe.BzlLoadFailedException;
import com.google.devtools.build.lib.skyframe.BzlLoadValue;
import com.google.devtools.build.lib.skyframe.StarlarkBuiltinsValue;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;

/**
 * Utility class for loading a Starlark exec transition from source and making it available as an
 * {@link StarlarkAttributeTransitionProvider}.
 */
public final class StarlarkExecTransitionLoader {

  /** Thrown when the Starlark transition failed to load. */
  public static class StarlarkExecTransitionLoadingException extends Exception {
    public StarlarkExecTransitionLoadingException(String context, String ref, String message) {
      super(
          String.format(
              "Bad Starlark transition reference from %s: %s. %s.", context, ref, message));
    }
  }

  /** Caller-provided logic for Skyframe-evaluating {@link BzlLoadValue.Key}s. */
  public interface BzlFileLoader {
    /**
     * Loads the given {@link BzlLoadValue.Key}. Returns null if not all Skyframe deps are ready.
     */
    @Nullable
    BzlLoadValue getValue(BzlLoadValue.Key key) throws BzlLoadFailedException, InterruptedException;
  }

  /**
   * Loads the Starlark transition that implements execution transition logic according to {@link
   * CoreOptions#starlarkExecConfig}.
   *
   * @param options the current configured target's {@link BuildOptions}. This is used to find the
   *     value for {@link CoreOptions#starlarkExecConfig}.
   * @param bzlFileLoader caller-provided logic for loading {@link BzlLoadValue.Key} skyvalues.
   * @return null if Skyframe deps need loading. A filled {@link Optional} if this build implements
   *     the exec transition with a Starlark transition. An empty {@link Optional} if this build
   *     implements the exec transition with native logic.
   * @throws StarlarkExecTransitionLoadingException if the desired transition isn't a valid Starlark
   *     exec transition.
   */
  @Nullable
  public static Optional<StarlarkAttributeTransitionProvider> loadStarlarkExecTransition(
      @Nullable BuildOptions options, BzlFileLoader bzlFileLoader)
      throws StarlarkExecTransitionLoadingException, InterruptedException {
    if (options == null || options.equals(CommonOptions.EMPTY_OPTIONS)) {
      return Optional.empty();
    }
    String userRef =
        Verify.verifyNotNull(
            options.get(CoreOptions.class).starlarkExecConfig,
            "Cannot apply the exec transition since no transition is defined for this build.");
    final String flagName = "--experimental_exec_config";
    TransitionReference parsedRef = TransitionReference.create(userRef, flagName);
    BzlLoadValue bzlValue;
    try {
      bzlValue =
          bzlFileLoader.getValue(
              Objects.equals(
                      parsedRef.bzlFile().getRepository(), StarlarkBuiltinsValue.BUILTINS_REPO)
                  ? BzlLoadValue.keyForBuiltins(parsedRef.bzlFile())
                  : BzlLoadValue.keyForBuild(parsedRef.bzlFile()));
    } catch (BzlLoadFailedException e) {
      throw new StarlarkExecTransitionLoadingException(flagName, userRef, e.getMessage());
    }
    if (bzlValue == null) {
      return null;
    }
    Object transition = bzlValue.getModule().getGlobal(parsedRef.starlarkSymbolName());
    if (transition == null) {
      throw new StarlarkExecTransitionLoadingException(
          flagName,
          userRef,
          String.format("%s not found in %s", parsedRef.starlarkSymbolName(), parsedRef.bzlFile()));
    } else if (!(transition instanceof StarlarkDefinedConfigTransition)) {
      throw new StarlarkExecTransitionLoadingException(
          flagName, userRef, parsedRef.starlarkSymbolName() + " is not a Starlark transition");
    }
    return Optional.of(
        new StarlarkExecTransitionProvider((StarlarkDefinedConfigTransition) transition));
  }

  /** A marker class to distinguish the exec transition from other starlark transitions. */
  static class StarlarkExecTransitionProvider extends StarlarkAttributeTransitionProvider {
    StarlarkExecTransitionProvider(StarlarkDefinedConfigTransition execTransition) {
      super(execTransition);
    }

    @Override
    public boolean allowImmutableFlagChanges() {
      // The exec transition must be allowed to change otherwise immutable flags.
      return true;
    }
  }

  /**
   * Structured form of a Starlark transition reference.
   *
   * <p>In other words, structured form of <code>//pkg:def.bzl%transition_name</code>
   */
  @AutoValue
  abstract static class TransitionReference {

    /** The .bzl file where this transition is defined. */
    abstract Label bzlFile();

    /** The transition's Starlark symbol name. */
    abstract String starlarkSymbolName();

    /**
     * Returns a structured form of a user-specified Starlark transition reference.
     *
     * @throws StarlarkExecTransitionLoadingException on parsing errors.
     */
    static TransitionReference create(String userRef, String context)
        throws StarlarkExecTransitionLoadingException {
      List<String> splitval = Splitter.on('%').splitToList(userRef);
      if (splitval.size() < 2 || splitval.get(1).isEmpty()) {
        throw new StarlarkExecTransitionLoadingException(
            context, userRef, "Doesn't match expected form //pkg:file.bzl%%symbol");
      }
      try {
        return new AutoValue_StarlarkExecTransitionLoader_TransitionReference(
            Label.parseCanonical(splitval.get(0)), splitval.get(1));
      } catch (LabelSyntaxException e) {
        throw new StarlarkExecTransitionLoadingException(
            context, userRef, String.format("Bad label %s: %s", splitval.get(0), e.getMessage()));
      }
    }
  }

  private StarlarkExecTransitionLoader() {}
}
