// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInsight.daemon.impl;

import com.intellij.codeInsight.daemon.DaemonBundle;
import com.intellij.codeInsight.daemon.impl.actions.ShowErrorDescriptionAction;
import com.intellij.codeInsight.hint.LineTooltipRenderer;
import com.intellij.codeInsight.hint.TooltipLinkHandlerEP;
import com.intellij.codeInspection.ui.InspectionNodeInfo;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.Html;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NonNls;
import javax.annotation.Nonnull;

import javax.annotation.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.List;

class DaemonTooltipRenderer extends LineTooltipRenderer {
  @NonNls
  protected static final String END_MARKER = "<!-- end marker -->";


  DaemonTooltipRenderer(final String text, Object[] comparable) {
    super(text, comparable);
  }

  DaemonTooltipRenderer(final String text, final int width, Object[] comparable) {
    super(text, width, comparable);
  }

  @Override
  protected void onHide(@Nonnull JComponent contentComponent) {
    ShowErrorDescriptionAction.rememberCurrentWidth(contentComponent.getWidth());
  }

  @Nonnull
  @Override
  protected String dressDescription(@Nonnull final Editor editor, @Nonnull String tooltipText, boolean expand) {
    if (!expand) {
      return super.dressDescription(editor, tooltipText, false);
    }

    final List<String> problems = getProblems(tooltipText);
    StringBuilder text = new StringBuilder();
    for (String problem : problems) {
      final String ref = getLinkRef(problem);
      if (ref != null) {
        String description = TooltipLinkHandlerEP.getDescription(ref, editor);
        if (description != null) {
          description = InspectionNodeInfo.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(new Html(description).setKeepFont(true)));
          text.append(getHtmlForProblemWithLink(problem)).append(END_MARKER).append("<p>").append("<span style=\"color:").append(ColorUtil.toHex(getDescriptionTitleColor())).append("\">")
                  .append(TooltipLinkHandlerEP.getDescriptionTitle(ref, editor)).append(":</span>").append(description).append(UIUtil.BORDER_LINE);
        }
      }
      else {
        text.append(UIUtil.getHtmlBody(new Html(problem).setKeepFont(true))).append(UIUtil.BORDER_LINE);
      }
    }
    if (text.length() > 0) { //otherwise do not change anything
      return XmlStringUtil.wrapInHtml(StringUtil.trimEnd(text.toString(), UIUtil.BORDER_LINE));
    }
    return super.dressDescription(editor, tooltipText, true);
  }

  @Nonnull
  protected List<String> getProblems(@Nonnull String tooltipText) {
    return StringUtil.split(UIUtil.getHtmlBody(new Html(tooltipText).setKeepFont(true)), UIUtil.BORDER_LINE);
  }

  @Nonnull
  protected String getHtmlForProblemWithLink(@Nonnull String problem) {
    Html html = new Html(problem).setKeepFont(true);
    return UIUtil.getHtmlBody(html).replace(DaemonBundle.message("inspection.extended.description"), DaemonBundle.message("inspection.collapse.description"));
  }

  @Nullable
  protected static String getLinkRef(@NonNls String text) {
    final String linkWithRef = "<a href=\"";
    final int linkStartIdx = text.indexOf(linkWithRef);
    if (linkStartIdx >= 0) {
      final String ref = text.substring(linkStartIdx + linkWithRef.length());
      final int quoteIdx = ref.indexOf('"');
      if (quoteIdx > 0) {
        return ref.substring(0, quoteIdx);
      }
    }
    return null;
  }

  @Nonnull
  protected Color getDescriptionTitleColor() {
    return JBColor.namedColor("ToolTip.infoForeground", new JBColor(0x919191, 0x919191));
  }

  @Nonnull
  @Override
  public LineTooltipRenderer createRenderer(@Nullable String text, final int width) {
    return new DaemonTooltipRenderer(text, width, getEqualityObjects());
  }
}