// Copyright 2018 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.skydoc.rendering;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.syntax.FunctionSignature;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.syntax.StringLiteral;
import com.google.devtools.build.lib.syntax.UserDefinedFunction;
import com.google.devtools.skylark.common.DocstringUtils;
import com.google.devtools.skylark.common.DocstringUtils.DocstringInfo;
import com.google.devtools.skylark.common.DocstringUtils.DocstringParseError;
import com.google.devtools.skylark.common.DocstringUtils.ParameterDoc;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/** Encapsulates information about a user-defined Starlark function. */
public class UserDefinedFunctionInfo {

  private final String functionName;
  private final Collection<FunctionParamInfo> parameters;
  private final String docString;

  /**
   * An exception that may be thrown during construction of {@link UserDefinedFunctionInfo} if the
   * function's docstring is malformed.
   */
  public static class DocstringParseException extends Exception {
    public DocstringParseException(
        String functionName, Location definedLocation, List<DocstringParseError> parseErrors) {
      super(getMessage(functionName, definedLocation, parseErrors));
    }

    private static String getMessage(
        String functionName, Location definedLocation, List<DocstringParseError> parseErrors) {
      StringBuilder message = new StringBuilder();
      message.append(
          String.format(
              "Unable to generate documentation for function %s (defined at %s) "
                  + "due to malformed docstring. Parse errors:\n",
              functionName, definedLocation));
      for (DocstringParseError parseError : parseErrors) {
        message.append(
            String.format(
                "  %s line %s: %s\n",
                definedLocation,
                parseError.getLineNumber(),
                parseError.getMessage().replace('\n', ' ')));
      }
      return message.toString();
    }
  }

  /**
   * Create and return a {@link UserDefinedFunctionInfo} object encapsulating information obtained
   * from the given function and from its parsed docstring.
   *
   * @param functionName the name of the function in the target scope. (Note this is not necessarily
   *     the original exported function name; the function may have been renamed in the target
   *     Starlark file's scope)
   * @param userDefinedFunction the raw function object
   * @throws DocstringParseException if the function's docstring is malformed
   */
  public static UserDefinedFunctionInfo fromNameAndFunction(
      String functionName, UserDefinedFunction userDefinedFunction) throws DocstringParseException {
    String functionDescription = "";
    Map<String, String> paramNameToDocMap = Maps.newLinkedHashMap();

    StringLiteral docStringLiteral =
        DocstringUtils.extractDocstring(userDefinedFunction.getStatements());

    if (docStringLiteral != null) {
      List<DocstringParseError> parseErrors = Lists.newArrayList();
      DocstringInfo docstringInfo = DocstringUtils.parseDocstring(docStringLiteral, parseErrors);
      if (!parseErrors.isEmpty()) {
        throw new DocstringParseException(
            functionName, userDefinedFunction.getLocation(), parseErrors);
      }
      functionDescription += docstringInfo.getSummary();
      if (!docstringInfo.getSummary().isEmpty() && !docstringInfo.getLongDescription().isEmpty()) {
        functionDescription += "\n\n";
      }
      functionDescription += docstringInfo.getLongDescription();
      for (ParameterDoc paramDoc : docstringInfo.getParameters()) {
        paramNameToDocMap.put(paramDoc.getParameterName(), paramDoc.getDescription());
      }
    }

    return new UserDefinedFunctionInfo(
        functionName,
        parameterInfos(userDefinedFunction, paramNameToDocMap),
        functionDescription);
  }

  private static List<FunctionParamInfo> parameterInfos(
      UserDefinedFunction userDefinedFunction,
      Map<String, String> paramNameToDocMap)  {
    FunctionSignature.WithValues<Object, SkylarkType> signature =
        userDefinedFunction.getSignature();
    ImmutableList.Builder<FunctionParamInfo> parameterInfos = ImmutableList.builder();

    List<String> paramNames = signature.getSignature().getNames();
    // Mandatory parameters must always come before optional parameters, so this counts
    // down until all mandatory parameters have been exhausted, and then starts filling in
    // the default parameters accordingly.
    int numMandatoryParamsLeft =
        signature.getDefaultValues() != null
            ? paramNames.size() - signature.getDefaultValues().size()
            : paramNames.size();
    int optionalParamIndex = 0;

    for (String paramName : paramNames) {
      Object defaultParamValue = null;
      String paramDoc = "";
      if (numMandatoryParamsLeft == 0) {
        defaultParamValue = signature.getDefaultValues().get(optionalParamIndex);
        optionalParamIndex++;
      } else {
        numMandatoryParamsLeft--;
      }
      if (paramNameToDocMap.containsKey(paramName)) {
        paramDoc = paramNameToDocMap.get(paramName);
      }
      parameterInfos.add(new FunctionParamInfo(paramName, paramDoc, defaultParamValue));
    }
    return parameterInfos.build();
  }

  private UserDefinedFunctionInfo(
      String functionName, Collection<FunctionParamInfo> parameters, String docString) {
    this.functionName = functionName;
    this.parameters = parameters;
    this.docString = docString;
  }

  /** Returns the raw name of this function, for example, "my_function". */
  public String getName() {
    return functionName;
  }

  /**
   * Returns a collection of {@link FunctionParamInfo} objects, where each encapsulates information
   * about what of the function parameters. Ordering matches the actual Starlark function signature.
   */
  public Collection<FunctionParamInfo> getParameters() {
    return parameters;
  }

  /**
   * Returns the portion of the docstring that is not part of any special sections, such as "Args:"
   * or "Returns:". Returns the empty string if there is no docstring literal for this function.
   */
  public String getDocString() {
    return docString;
  }
}
