// 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.query2.cquery;

import static com.google.devtools.build.lib.analysis.config.StarlarkDefinedConfigTransition.COMMAND_LINE_OPTION_PREFIX;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.configuredtargets.AbstractConfiguredTarget;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.TargetAccessor;
import com.google.devtools.build.lib.query2.engine.QueryException;
import com.google.devtools.build.lib.server.FailureDetails.ConfigurableQuery;
import com.google.devtools.build.lib.server.FailureDetails.Query;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.common.options.OptionDefinition;
import com.google.devtools.common.options.OptionsParser;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.Map;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Module;
import net.starlark.java.eval.Mutability;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkFunction;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.eval.StarlarkThread;
import net.starlark.java.syntax.Expression;
import net.starlark.java.syntax.FileOptions;
import net.starlark.java.syntax.ParserInput;
import net.starlark.java.syntax.StarlarkFile;
import net.starlark.java.syntax.SyntaxError;

/**
 * Starlark output formatter for cquery results. Each configured target will result in an evaluation
 * of the Starlark expression specified by {@code --expr}.
 */
public class StarlarkOutputFormatterCallback extends CqueryThreadsafeCallback {
  private class CqueryDialectGlobals {
    @StarlarkMethod(
        name = "build_options",
        documented = false,
        parameters = {
          @Param(name = "target"),
        })
    public Object buildOptions(ConfiguredTarget target) {
      BuildConfigurationValue config = getConfiguration(target.getConfigurationKey());

      if (config == null) {
        // config is null for input file configured targets.
        return Starlark.NONE;
      }

      BuildOptions buildOptions = config.getOptions();
      ImmutableMap.Builder<String, Object> result = ImmutableMap.builder();

      // Add all build options from each native configuration fragment.
      for (FragmentOptions fragmentOptions : buildOptions.getNativeOptions()) {
        Class<? extends FragmentOptions> optionClass = fragmentOptions.getClass();
        for (OptionDefinition def : OptionsParser.getOptionDefinitions(optionClass)) {
          String optionName = def.getOptionName();
          String optionKey = COMMAND_LINE_OPTION_PREFIX + optionName;

          try {
            Field field = def.getField();
            FragmentOptions options = buildOptions.get(optionClass);
            Object optionValue = field.get(options);

            try {
              // fromJava is not a deep validity check.
              // It is not guaranteed to catch all errors,
              // nor does it specify how it reports the errors it does find.
              // Passing arbitrary Java values into the Starlark interpreter
              // is not safe.
              // TODO(cparsons,twigg): fix it: convert value by explicit cases.
              result.put(optionKey, Starlark.fromJava(optionValue, null));
            } catch (IllegalArgumentException | NullPointerException ex) {
              // optionValue is not a valid Starlark value, so skip this option.
              // (e.g. tristate; a map with null values)
            }
          } catch (IllegalAccessException e) {
            throw new IllegalStateException(e);
          }
        }
      }

      // Add Starlark options.
      for (Map.Entry<Label, Object> e : buildOptions.getStarlarkOptions().entrySet()) {
        result.put(e.getKey().toString(), e.getValue());
      }
      return result.buildOrThrow();
    }

    @StarlarkMethod(
        name = "providers",
        documented = false,
        parameters = {
          @Param(name = "target"),
        })
    public Object providers(ConfiguredTarget target) {
      if (!(target instanceof AbstractConfiguredTarget)) {
        return Starlark.NONE;
      }
      Dict<String, Object> ret = ((AbstractConfiguredTarget) target).getProvidersDict();
      if (ret == null) {
        return Starlark.NONE;
      }
      return ret;
    }
  }

  private static final Object[] NO_ARGS = new Object[0];

  // Starlark function with single required parameter "target", a ConfiguredTarget query result.
  private final StarlarkFunction formatFn;

  StarlarkOutputFormatterCallback(
      ExtendedEventHandler eventHandler,
      CqueryOptions options,
      OutputStream out,
      SkyframeExecutor skyframeExecutor,
      TargetAccessor<KeyedConfiguredTarget> accessor)
      throws QueryException, InterruptedException {
    super(eventHandler, options, out, skyframeExecutor, accessor, /*uniquifyResults=*/ false);

    ParserInput input = null;
    String exceptionMessagePrefix;
    if (!options.file.isEmpty()) {
      if (!options.expr.isEmpty()) {
        throw new QueryException(
            "You must not specify both --starlark:expr and --starlark:file",
            Query.Code.ILLEGAL_FLAG_COMBINATION);
      }
      exceptionMessagePrefix = "invalid --starlark:file: ";
      try {
        input = ParserInput.readFile(options.file);
      } catch (IOException ex) {
        throw new QueryException(
            exceptionMessagePrefix + "failed to read " + ex.getMessage(),
            Query.Code.QUERY_FILE_READ_FAILURE);
      }
    } else {
      exceptionMessagePrefix = "invalid --starlark:expr: ";
      String expr = options.expr.isEmpty() ? "str(target.label)" : options.expr;
      // Validate that options.expr is a pure expression (for example, that it does not attempt
      // to escape its scope via unbalanced parens).
      ParserInput exprParserInput = ParserInput.fromString(expr, "--starlark:expr");
      try {
        Expression.parse(exprParserInput);
      } catch (SyntaxError.Exception ex) {
        throw new QueryException(
            exceptionMessagePrefix + ex.getMessage(), ConfigurableQuery.Code.STARLARK_SYNTAX_ERROR);
      }

      // Create a synthetic file that defines a function with single parameter "target",
      // whose body is provided by the user's expression. Dynamic errors will have the wrong column.
      String fileBody = "def format(target): return (" + expr + ")";
      input = ParserInput.fromString(fileBody, "--starlark:expr");
    }

    StarlarkFile file = StarlarkFile.parse(input, FileOptions.DEFAULT);
    if (!file.ok()) {
      Event.replayEventsOn(eventHandler, file.errors());
    }
    try (Mutability mu = Mutability.create("formatter")) {
      ImmutableMap.Builder<String, Object> env = ImmutableMap.builder();
      Starlark.addMethods(env, new CqueryDialectGlobals(), StarlarkSemantics.DEFAULT);
      Module module = Module.withPredeclared(StarlarkSemantics.DEFAULT, env.buildOrThrow());

      StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
      Starlark.execFile(input, FileOptions.DEFAULT, module, thread);
      Object formatFn = module.getGlobal("format");
      if (formatFn == null) {
        throw new QueryException(
            exceptionMessagePrefix + "file does not define 'format'",
            ConfigurableQuery.Code.FORMAT_FUNCTION_ERROR);
      }
      if (!(formatFn instanceof StarlarkFunction)) {
        throw new QueryException(
            exceptionMessagePrefix
                + "got "
                + Starlark.type(formatFn)
                + " for 'format', want function",
            ConfigurableQuery.Code.FORMAT_FUNCTION_ERROR);
      }
      this.formatFn = (StarlarkFunction) formatFn;
      if (this.formatFn.getParameterNames().size() != 1) {
        throw new QueryException(
            exceptionMessagePrefix + "'format' function must take exactly 1 argument",
            ConfigurableQuery.Code.FORMAT_FUNCTION_ERROR);
      }
    } catch (SyntaxError.Exception ex) {
      throw new QueryException(
          exceptionMessagePrefix + ex.getMessage(), ConfigurableQuery.Code.STARLARK_SYNTAX_ERROR);
    } catch (EvalException ex) {
      throw new QueryException(
          exceptionMessagePrefix + ex.getMessageWithStack(),
          ConfigurableQuery.Code.STARLARK_EVAL_ERROR);
    }
  }

  @Override
  public String getName() {
    return "starlark";
  }

  @Override
  public void processOutput(Iterable<KeyedConfiguredTarget> partialResult)
      throws InterruptedException {
    for (KeyedConfiguredTarget target : partialResult) {
      try {
        StarlarkThread thread =
            new StarlarkThread(Mutability.create("cquery evaluation"), StarlarkSemantics.DEFAULT);
        thread.setMaxExecutionSteps(500_000L);

        // Invoke formatFn with `target` argument.
        Object result =
            Starlark.fastcall(
                thread, this.formatFn, new Object[] {target.getConfiguredTarget()}, NO_ARGS);

        addResult(Starlark.str(result, thread.getSemantics()));
      } catch (EvalException ex) {
        eventHandler.handle(
            Event.error(
                String.format(
                    "Starlark evaluation error for %s: %s",
                    target.getLabel(), ex.getMessageWithStack())));
        continue;
      }
    }
  }
}
