/*
 * Copyright 2016 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.idea.blaze.base.lang.buildfile.documentation;

import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpec;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProvider;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.RuleDefinition;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.DocStringOwner;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.FunctionStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.ParameterList;
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.codeInsight.documentation.DocumentationManagerProtocol;
import com.intellij.lang.documentation.AbstractDocumentationProvider;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import javax.annotation.Nullable;

/** Provides quick docs for some BUILD elements. */
public class BuildDocumentationProvider extends AbstractDocumentationProvider {

  private static final String LINK_TYPE_FILE = "#file#";

  @Nullable
  @Override
  public String generateDoc(PsiElement element, @Nullable PsiElement originalElement) {
    if (element instanceof DocStringOwner) {
      return buildDocs((DocStringOwner) element);
    }
    if (element instanceof FuncallExpression) {
      return docsForBuiltInRule(
          element.getProject(), ((FuncallExpression) element).getFunctionName());
    }
    return null;
  }

  /** Returns the corresponding built-in rule in the BUILD file language, if one exists. */
  @Nullable
  private static RuleDefinition getBuiltInRule(Project project, @Nullable String ruleName) {
    BuildLanguageSpec spec = BuildLanguageSpecProvider.getInstance().getLanguageSpec(project);
    return spec != null ? spec.getRule(ruleName) : null;
  }

  @Nullable
  private static String docsForBuiltInRule(Project project, @Nullable String ruleName) {
    RuleDefinition rule = getBuiltInRule(project, ruleName);
    if (rule == null) {
      return null;
    }
    String link = Blaze.getBuildSystemProvider(project).getRuleDocumentationUrl(rule);
    if (link == null) {
      return null;
    }
    return String.format(
        "External documentation for %s:<br><a href=\"%s\">%s</a>", rule.name, link, link);
  }

  private static void describeFile(PsiFile file, StringBuilder builder, boolean linkToFile) {
    if (!(file instanceof BuildFile)) {
      return;
    }
    BuildFile buildFile = (BuildFile) file;
    Label label = buildFile.getBuildLabel();
    String name = label != null ? label.toString() : buildFile.getPresentableText();
    if (linkToFile) {
      builder
          .append("<a href=\"")
          .append(DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL)
          .append(LINK_TYPE_FILE)
          .append("\">")
          .append(name)
          .append("</a>");
    } else {
      builder.append(String.format("<b>%s</b>", name));
    }
    builder.append("<br><br>");
  }

  private static String buildDocs(DocStringOwner element) {
    StringBuilder docs = new StringBuilder();
    describeFile(element.getContainingFile(), docs, !(element instanceof BuildFile));

    if (element instanceof FunctionStatement) {
      describeFunction((FunctionStatement) element, docs);
    }
    StringLiteral docString = element.getDocString();
    if (docString != null) {
      docs.append(DocStringFormatter.formatDocString(docString, element));
    }
    return wrapDocInHtml(docs.toString());
  }

  private static void describeFunction(FunctionStatement function, StringBuilder builder) {
    // just show the function declaration verbatim, including the parameter list.
    ParameterList paramList = function.getParameterList();
    if (paramList == null) {
      return;
    }
    builder
        .append("def ")
        .append("<b>")
        .append(function.getName())
        .append("</b>")
        .append(paramList.getNode().getChars())
        .append("<br><br>");
  }

  private static String wrapDocInHtml(String doc) {
    return "<html><body><code>" + doc + "</code></body></html>";
  }

  @Nullable
  @Override
  public PsiElement getDocumentationElementForLink(
      PsiManager psiManager, String link, PsiElement context) {
    if (link.equals(LINK_TYPE_FILE)) {
      return context.getContainingFile();
    }
    return null;
  }
}
