// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Helper for creating HTML visualization of the source map information
/// generated by a [SourceMapProcessor].

library sourcemap.html.helper;

import 'dart:convert';
import 'dart:math' as Math;

import 'package:compiler/src/io/source_file.dart';
import 'package:compiler/src/io/source_information.dart';
import 'package:compiler/src/js/js.dart' as js;

import 'colors.dart';
import 'sourcemap_helper.dart';
import 'sourcemap_html_templates.dart';
import 'html_parts.dart';

/// Truncate [input] to [length], adding '...' if truncated.
String truncate(String input, int length) {
  if (input.length > length) {
    return '${input.substring(0, length - 3)}...';
  }
  return input;
}

const int HUE_COUNT = 24;

/// Returns the [index]th color for visualization.
HSV toColor(int index) {
  double h = 360.0 * (index % HUE_COUNT) / HUE_COUNT;
  double v = 1.0;
  double s = 0.5;
  return HSV(h, s, v);
}

/// Return the CSS color value for the [index]th color.
String toColorCss(int index) {
  return toColor(index).toCss;
}

/// Return the CSS color value for the [index]th span.
String toPattern(int index) {
  /// Use gradient on spans to visually identify consecutive spans mapped to the
  /// same source location.
  HSV startColor = toColor(index);
  HSV endColor = HSV(startColor.h, startColor.s + 0.4, startColor.v - 0.2);
  return 'linear-gradient(to right, ${startColor.toCss}, ${endColor.toCss})';
}

/// Return the html for the [index] line number. If [width] is provided, shorter
/// line numbers will be prefixed with spaces to match the width.
String lineNumber(int index,
    {int? width, bool useNbsp = false, String? className}) {
  if (className == null) {
    className = 'lineNumber';
  }
  String text = '${index + 1}';
  String padding = useNbsp ? '&nbsp;' : ' ';
  if (width != null && text.length < width) {
    text = (padding * (width - text.length)) + text;
  }
  return '<span class="$className">$text$padding</span>';
}

/// Return the html escaped [text].
String escape(String text) {
  return const HtmlEscape().convert(text);
}

/// Information needed to generate HTML for a single [SourceMapInfo].
class SourceMapHtmlInfo {
  final SourceMapInfo sourceMapInfo;
  final CodeProcessor codeProcessor;
  final SourceLocationCollection sourceLocationCollection;

  SourceMapHtmlInfo(
      this.sourceMapInfo, this.codeProcessor, this.sourceLocationCollection);

  @override
  String toString() {
    return sourceMapInfo.toString();
  }
}

/// A collection of source locations.
///
/// Used to index source locations for visualization and linking.
class SourceLocationCollection {
  List<SourceLocation> sourceLocations = [];
  Map<SourceLocation, int> sourceLocationIndexMap;

  SourceLocationCollection([SourceLocationCollection? parent])
      : sourceLocationIndexMap =
            parent == null ? {} : parent.sourceLocationIndexMap;

  int registerSourceLocation(SourceLocation sourceLocation) {
    return sourceLocationIndexMap.putIfAbsent(sourceLocation, () {
      sourceLocations.add(sourceLocation);
      return sourceLocationIndexMap.length;
    });
  }

  int getIndex(SourceLocation sourceLocation) {
    return sourceLocationIndexMap[sourceLocation]!;
  }
}

abstract class CssColorScheme {
  String singleLocationToCssColor(int id);

  String multiLocationToCssColor(List<int> ids);

  bool get showLocationAsSpan;
}

class PatternCssColorScheme implements CssColorScheme {
  const PatternCssColorScheme();

  @override
  bool get showLocationAsSpan => true;

  @override
  String singleLocationToCssColor(int index) {
    return "background:${toPattern(index)};";
  }

  @override
  String multiLocationToCssColor(List<int> indices) {
    StringBuffer sb = StringBuffer();
    double delta = 100.0 / (indices.length);
    double position = 0.0;

    void addColor(String color) {
      sb.write(', ${color} ${position.toInt()}%');
      position += delta;
      sb.write(', ${color} ${position.toInt()}%');
    }

    for (int index in indices) {
      addColor('${toColorCss(index)}');
    }
    return 'background: linear-gradient(to right${sb}); '
        'background-size: 10px 10px;';
  }
}

class SingleColorScheme implements CssColorScheme {
  const SingleColorScheme();

  @override
  bool get showLocationAsSpan => false;

  @override
  String singleLocationToCssColor(int index) {
    return "background:${toColorCss(index)};";
  }

  @override
  String multiLocationToCssColor(List<int> indices) {
    StringBuffer sb = StringBuffer();
    double delta = 100.0 / (indices.length);
    double position = 0.0;

    void addColor(String color) {
      sb.write(', ${color} ${position.toInt()}%');
      position += delta;
      sb.write(', ${color} ${position.toInt()}%');
    }

    for (int index in indices) {
      addColor('${toColorCss(index)}');
    }
    return 'background: linear-gradient(to bottom${sb}); '
        'background-size: 10px 3px;';
  }
}

/// Processor that computes the HTML representation of a block of JavaScript
/// code and collects the source locations mapped in the code.
class CodeProcessor {
  int lineIndex = 0;
  final String name;
  int currentJsSourceOffset = 0;
  final SourceLocationCollection collection;
  final Map<int, List<SourceLocation>> codeLocations = {};
  final CssColorScheme colorScheme;

  CodeProcessor(this.name, this.collection,
      {this.colorScheme = const PatternCssColorScheme()});

  void addSourceLocation(int targetOffset, SourceLocation sourceLocation) {
    codeLocations.putIfAbsent(targetOffset, () => []).add(sourceLocation);
    collection.registerSourceLocation(sourceLocation);
  }

  String convertToHtml(String text) {
    List<Annotation> annotations = <Annotation>[];
    codeLocations.forEach((int codeOffset, List<SourceLocation> locations) {
      for (SourceLocation location in locations) {
        annotations.add(new Annotation(
            collection.getIndex(location), codeOffset, location.shortText));
      }
    });
    return convertAnnotatedCodeToHtml(text, annotations,
        colorScheme: colorScheme,
        elementScheme: HighlightLinkScheme(name),
        windowSize: 3);
  }
}

class ElementScheme {
  const ElementScheme();

  String? getName(int id, Set<int> ids) => null;
  String? getHref(int id, Set<int> ids) => null;
  String? onClick(int id, Set<int> ids) => null;
  String? onMouseOver(int id, Set<int> ids) => null;
  String? onMouseOut(int id, Set<int> ids) => null;
}

class HighlightLinkScheme implements ElementScheme {
  final String name;

  HighlightLinkScheme(this.name);

  @override
  String getName(int id, Set<int> indices) {
    return 'js$id';
  }

  @override
  String getHref(int id, Set<int> indices) {
    return "#${id}";
  }

  @override
  String onClick(int id, Set<int> indices) {
    return "show(\'$name\');";
  }

  @override
  String onMouseOut(int id, Set<int> indices) {
    return "highlight([]);";
  }

  @override
  String onMouseOver(int id, Set<int> indices) {
    String onmouseover = indices.map((i) => '\'$i\'').join(',');
    return "highlight([${onmouseover}]);";
  }
}

String convertAnnotatedCodeToHtml(String code, Iterable<Annotation> annotations,
    {CssColorScheme colorScheme = const SingleColorScheme(),
    required ElementScheme elementScheme,
    required int windowSize}) {
  StringBuffer htmlBuffer = StringBuffer();
  List<CodeLine> lines = convertAnnotatedCodeToCodeLines(code, annotations,
      windowSize: windowSize);
  int? lineNoWidth;
  if (lines.isNotEmpty) {
    lineNoWidth = '${lines.last.lineNo + 1}'.length;
  }
  HtmlPrintContext context = HtmlPrintContext(
      lineNoWidth: lineNoWidth,
      getAnnotationData: createAnnotationDataFunction(
          colorScheme: colorScheme, elementScheme: elementScheme));
  for (CodeLine line in lines) {
    line.printHtmlOn(htmlBuffer, context);
  }
  return htmlBuffer.toString();
}

List<CodeLine> convertAnnotatedCodeToCodeLines(
    String code, Iterable<Annotation> annotations,
    {int? startLine, int? endLine, int? windowSize, Uri? uri}) {
  List<CodeLine> lines = <CodeLine>[];
  CodeLine? currentLine;
  final List<Annotation> currentAnnotations = <Annotation>[];
  int offset = 0;
  int lineIndex = 0;
  late final int firstLine;
  late final int lastLine;

  void addCode(String code) {
    if (currentLine != null) {
      currentLine!.codeBuffer.write(code);
      currentLine!.codeParts
          .add(new CodePart(currentAnnotations.toList(), code));
      currentAnnotations.clear();
    }
  }

  void addAnnotations(List<Annotation> annotations) {
    currentAnnotations.addAll(annotations);
    if (currentLine != null) {
      currentLine!.annotations.addAll(annotations);
    }
  }

  void beginLine(int currentOffset) {
    lines.add(currentLine = CodeLine(lines.length, currentOffset, uri: uri));
  }

  void endCurrentLocation() {
    if (currentAnnotations.isNotEmpty) {
      addCode('');
    }
  }

  void addSubstring(int until, {bool isFirst = false, bool isLast = false}) {
    if (until <= offset) return;
    if (offset >= code.length) return;

    String substring = code.substring(offset, until);
    bool first = true;

    if (isLast) {
      lastLine = lineIndex;
    }
    int localOffset = 0;
    if (isFirst) {
      beginLine(offset + localOffset);
    }
    for (String line in substring.split('\n')) {
      if (!first) {
        endCurrentLocation();
        lineIndex++;
        beginLine(offset + localOffset);
      }
      addCode(line);
      first = false;
      localOffset += line.length + 1;
    }
    if (isFirst) {
      firstLine = lineIndex;
    }
    offset = until;
  }

  void insertAnnotations(List<Annotation> annotations) {
    endCurrentLocation();
    addAnnotations(annotations);
  }

  Map<int, List<Annotation>> annotationMap = <int, List<Annotation>>{};
  for (Annotation annotation in annotations) {
    annotationMap
        .putIfAbsent(annotation.codeOffset, () => <Annotation>[])
        .add(annotation);
  }

  bool first = true;
  for (int codeOffset in annotationMap.keys.toList()..sort()) {
    List<Annotation> annotationList = annotationMap[codeOffset]!;
    addSubstring(codeOffset, isFirst: first);
    insertAnnotations(annotationList);
    first = false;
  }

  addSubstring(code.length, isFirst: first, isLast: true);
  endCurrentLocation();

  int start = startLine ?? 0;
  int end = endLine ?? lines.length - 1;
  if (lastLine == 0) lastLine = firstLine;
  if (windowSize != null) {
    start = Math.max(firstLine - windowSize, start);
    end = Math.min(lastLine + windowSize, end);
  }
  return lines.sublist(start, end);
}

/// Computes the HTML representation for a collection of JavaScript code blocks.
String computeJsHtml(Iterable<SourceMapHtmlInfo> infoList) {
  StringBuffer jsCodeBuffer = StringBuffer();
  for (SourceMapHtmlInfo info in infoList) {
    String name = info.sourceMapInfo.name!;
    String html = info.codeProcessor.convertToHtml(info.sourceMapInfo.code);
    String onclick = 'show(\'$name\');';
    jsCodeBuffer
        .write('<h3 onclick="$onclick">JS code for: ${escape(name)}</h3>\n');
    jsCodeBuffer.write('''
<pre>
$html
</pre>
''');
  }
  return jsCodeBuffer.toString();
}

/// Computes the HTML representation of the source mapping information for a
/// collection of JavaScript code blocks.
String computeJsTraceHtml(Iterable<SourceMapHtmlInfo> infoList) {
  StringBuffer jsTraceBuffer = StringBuffer();
  for (SourceMapHtmlInfo info in infoList) {
    String name = info.sourceMapInfo.name!;
    String jsTrace = computeJsTraceHtmlPart(
        info.sourceMapInfo.codePoints, info.sourceLocationCollection);
    jsTraceBuffer.write('''
<div name="$name" class="js-trace-buffer" style="display:none;">
<h3>Trace for: ${escape(name)}</h3>
$jsTrace
</div>
''');
  }
  return jsTraceBuffer.toString();
}

/// Computes the HTML information for the [info].
SourceMapHtmlInfo createHtmlInfo(
    SourceLocationCollection collection, SourceMapInfo info) {
  String name = info.name!;
  SourceLocationCollection subcollection = SourceLocationCollection(collection);
  CodeProcessor codeProcessor = CodeProcessor(name, subcollection);
  for (js.Node node in info.nodeMap.nodes) {
    info.nodeMap[node]!
        .forEach((int targetOffset, List<SourceLocation> sourceLocations) {
      for (SourceLocation sourceLocation in sourceLocations) {
        codeProcessor.addSourceLocation(targetOffset, sourceLocation);
      }
    });
  }
  return SourceMapHtmlInfo(info, codeProcessor, subcollection);
}

/// Outputs a HTML file in [jsMapHtmlUri] containing an interactive
/// visualization of the source mapping information in [infoList] computed
/// with the [sourceMapProcessor].
void createTraceSourceMapHtml(Uri jsMapHtmlUri,
    SourceMapProcessor sourceMapProcessor, Iterable<SourceMapInfo> infoList) {
  SourceFileManager sourceFileManager = sourceMapProcessor.sourceFileManager;
  SourceLocationCollection collection = SourceLocationCollection();
  List<SourceMapHtmlInfo> htmlInfoList = <SourceMapHtmlInfo>[];
  for (SourceMapInfo info in infoList) {
    htmlInfoList.add(createHtmlInfo(collection, info));
  }

  String jsCode = computeJsHtml(htmlInfoList);
  String dartCode = computeDartHtml(sourceFileManager, htmlInfoList);

  String jsTraceHtml = computeJsTraceHtml(htmlInfoList);
  outputJsDartTrace(jsMapHtmlUri, jsCode, dartCode, jsTraceHtml);
  print('Trace source map html generated: $jsMapHtmlUri');
}

/// Computes the HTML representation for the Dart code snippets referenced in
/// [infoList].
String computeDartHtml(
    SourceFileManager sourceFileManager, Iterable<SourceMapHtmlInfo> infoList) {
  StringBuffer dartCodeBuffer = StringBuffer();
  for (SourceMapHtmlInfo info in infoList) {
    dartCodeBuffer.write(computeDartHtmlPart(info.sourceMapInfo.name!,
        sourceFileManager, info.sourceLocationCollection));
  }
  return dartCodeBuffer.toString();
}

/// Computes the HTML representation for the Dart code snippets in [collection].
String computeDartHtmlPart(String name, SourceFileManager sourceFileManager,
    SourceLocationCollection collection,
    {bool showAsBlock = false}) {
  const int windowSize = 3;
  StringBuffer dartCodeBuffer = StringBuffer();
  Map<Uri, Map<int, List<SourceLocation>>> sourceLocationMap = {};
  collection.sourceLocations.forEach((SourceLocation sourceLocation) {
    if (sourceLocation.sourceUri == null) return;
    Map<int, List<SourceLocation>> uriMap =
        sourceLocationMap.putIfAbsent(sourceLocation.sourceUri!, () => {});
    List<SourceLocation> lineList =
        uriMap.putIfAbsent(sourceLocation.line - 1, () => []);
    lineList.add(sourceLocation);
  });
  sourceLocationMap.forEach((Uri uri, Map<int, List<SourceLocation>> uriMap) {
    SourceFile? sourceFile = sourceFileManager.getSourceFile(uri);
    if (sourceFile == null) {
      print('No source file for $uri');
      return;
    }
    StringBuffer codeBuffer = StringBuffer();

    int? firstLineIndex;
    int? lastLineIndex;
    List<int> lineIndices = uriMap.keys.toList()..sort();
    int? lineNoWidth;
    if (lineIndices.isNotEmpty) {
      lineNoWidth = '${lineIndices.last + windowSize + 1}'.length;
    }

    void flush() {
      if (firstLineIndex != null && lastLineIndex != null) {
        dartCodeBuffer.write('<h4>${uri.pathSegments.last}, '
            '${firstLineIndex! - windowSize + 1}-'
            '${lastLineIndex! + windowSize + 1}'
            '</h4>\n');
        dartCodeBuffer.write('<pre>\n');
        dartCodeBuffer.write('<p class="line">');
        for (int line = firstLineIndex! - windowSize;
            line < firstLineIndex!;
            line++) {
          if (line >= 0) {
            dartCodeBuffer.write('</p><p class="line">');
            dartCodeBuffer.write(lineNumber(line, width: lineNoWidth));
            dartCodeBuffer.write(sourceFile.kernelSource.getTextLine(line + 1));
          }
        }
        dartCodeBuffer.write(codeBuffer);
        for (int line = lastLineIndex! + 1;
            line <= lastLineIndex! + windowSize;
            line++) {
          if (line < sourceFile.lines) {
            dartCodeBuffer.write('</p><p class="line">');
            dartCodeBuffer.write(lineNumber(line, width: lineNoWidth));
            dartCodeBuffer.write(sourceFile.kernelSource.getTextLine(line + 1));
          }
        }
        dartCodeBuffer.write('</p>');
        dartCodeBuffer.write('</pre>\n');
        firstLineIndex = null;
        lastLineIndex = null;
      }
      codeBuffer.clear();
    }

    lineIndices.forEach((int lineIndex) {
      List<SourceLocation> locations = uriMap[lineIndex]!;
      if (lastLineIndex != null &&
          lastLineIndex! + windowSize * 4 < lineIndex) {
        flush();
      }
      if (firstLineIndex == null) {
        firstLineIndex = lineIndex;
      } else {
        for (int line = lastLineIndex! + 1; line < lineIndex; line++) {
          codeBuffer.write('</p><p class="line">');
          codeBuffer.write(lineNumber(line, width: lineNoWidth));
          codeBuffer.write(sourceFile.kernelSource.getTextLine(line + 1));
        }
      }
      String line = sourceFile.kernelSource.getTextLine(lineIndex + 1)!;
      locations.sort((a, b) => a.offset.compareTo(b.offset));
      for (int i = 0; i < locations.length; i++) {
        SourceLocation sourceLocation = locations[i];
        int index = collection.getIndex(sourceLocation);
        int start = sourceLocation.column - 1;
        int end = line.length;
        if (i + 1 < locations.length) {
          end = locations[i + 1].column - 1;
        }
        if (i == 0) {
          codeBuffer.write('</p><p class="line">');
          codeBuffer.write(lineNumber(lineIndex, width: lineNoWidth));
          codeBuffer.write(line.substring(0, start));
        }
        codeBuffer
            .write('<a name="${index}" style="background:${toPattern(index)};" '
                'title="[${lineIndex + 1},${start + 1}]" '
                'onmouseover="highlight(\'$index\');" '
                'onmouseout="highlight();">');
        codeBuffer.write(line.substring(start, end));
        codeBuffer.write('</a>');
      }
      lastLineIndex = lineIndex;
    });

    flush();
  });
  String display = showAsBlock ? 'block' : 'none';
  return '''
<div name="$name" class="dart-buffer" style="display:$display;">
<h3>Dart code for: ${escape(name)}</h3>
${dartCodeBuffer}
</div>''';
}

/// Computes a HTML visualization of the [codePoints].
String computeJsTraceHtmlPart(
    List<CodePoint> codePoints, SourceLocationCollection collection) {
  StringBuffer buffer = StringBuffer();
  buffer.write('<table style="width:100%;">');
  buffer.write('<tr><th>Node kind</th><th>JS code @ offset</th>'
      '<th>Dart code @ mapped location</th><th>file:position:name</th></tr>');
  codePoints.forEach((CodePoint codePoint) {
    String jsCode = truncate(codePoint.jsCode, 50);
    if (codePoint.sourceLocation != null) {
      int index = collection.getIndex(codePoint.sourceLocation!);
      String style = '';
      if (!codePoint.isMissing) {
        style = 'style="background:${toColorCss(index)};" ';

        buffer.write('<tr $style'
            'name="trace$index" '
            'onmouseover="highlight([${index}]);"'
            'onmouseout="highlight([]);">');
      } else {
        buffer.write('<tr>');
        print('${codePoint.sourceLocation} not found in ');
        collection.sourceLocationIndexMap.keys
            .where((l) => l.sourceUri == codePoint.sourceLocation!.sourceUri)
            .forEach((l) => print(' $l'));
      }
    } else {
      buffer.write('<tr>');
    }
    buffer.write('<td>${codePoint.kind}</td>');
    buffer.write('<td class="code">${codePoint.targetOffset}:${jsCode}</td>');
    if (codePoint.sourceLocation == null) {
      //buffer.write('<td></td>');
    } else {
      String dartCode = truncate(codePoint.dartCode!, 50);
      buffer.write('<td class="code">${dartCode}</td>');
      buffer.write('<td>${escape(codePoint.sourceLocation!.shortText)}</td>');
    }
    buffer.write('</tr>');
  });
  buffer.write('</table>');

  return buffer.toString();
}
