// Copyright (c) 2016, 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.

library sourcemap.diff_view;

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/diagnostics/invariant.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/io/position_information.dart';
import 'package:compiler/src/io/source_information.dart';
import 'package:compiler/src/io/source_file.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js/js_debug.dart';

import 'diff.dart';
import 'html_parts.dart';
import 'js_tracer.dart';
import 'output_structure.dart';
import 'sourcemap_helper.dart';
import 'sourcemap_html_helper.dart';
import 'trace_graph.dart';

const String WITH_SOURCE_INFO_STYLE = 'border: solid 1px #FF8080;';
const String WITHOUT_SOURCE_INFO_STYLE = 'background-color: #8080FF;';
const String ADDITIONAL_SOURCE_INFO_STYLE = 'border: solid 1px #80FF80;';
const String UNUSED_SOURCE_INFO_STYLE = 'border: solid 1px #8080FF;';

main(List<String> args) async {
  DEBUG_MODE = true;
  String out = 'out.js.diff_view.html';
  String filename;
  List<String> currentOptions = [];
  List<List<String>> optionSegments = [currentOptions];
  Map<int, String> loadFrom = {};
  Map<int, String> saveTo = {};
  int argGroup = 0;
  bool addAnnotations = true;
  for (String arg in args) {
    if (arg == '--') {
      currentOptions = [];
      optionSegments.add(currentOptions);
      argGroup++;
    } else if (arg == '-h') {
      addAnnotations = false;
      print('Hiding annotations');
    } else if (arg == '-l') {
      loadFrom[argGroup] = 'out.js.diff$argGroup.json';
    } else if (arg.startsWith('--load=')) {
      loadFrom[argGroup] = arg.substring('--load='.length);
    } else if (arg == '-s') {
      saveTo[argGroup] = 'out.js.diff$argGroup.json';
    } else if (arg.startsWith('--save=')) {
      saveTo[argGroup] = arg.substring('--save='.length);
    } else if (arg.startsWith('-o')) {
      out = arg.substring('-o'.length);
    } else if (arg.startsWith('--out=')) {
      out = arg.substring('--out='.length);
    } else if (arg.startsWith('-')) {
      currentOptions.add(arg);
    } else {
      filename = arg;
    }
  }
  List<String> commonArguments = optionSegments[0];
  List<List<String>> options = <List<String>>[];
  if (optionSegments.length == 1) {
    // Use default options; comparing SSA and CPS output using the new
    // source information strategy.
    options.add([USE_NEW_SOURCE_INFO]..addAll(commonArguments));
    options.add([USE_NEW_SOURCE_INFO, Flags.useCpsIr]..addAll(commonArguments));
  } else if (optionSegments.length == 2) {
    // Use alternative options for the second output column.
    options.add(commonArguments);
    options.add(optionSegments[1]..addAll(commonArguments));
  } else {
    // Use specific options for both output columns.
    options.add(optionSegments[1]..addAll(commonArguments));
    options.add(optionSegments[2]..addAll(commonArguments));
  }

  SourceFileManager sourceFileManager = new IOSourceFileManager(Uri.base);
  List<AnnotatedOutput> outputs = <AnnotatedOutput>[];
  for (int i = 0; i < 2; i++) {
    AnnotatedOutput output;
    if (loadFrom.containsKey(i)) {
      output = AnnotatedOutput.loadOutput(loadFrom[i]);
    } else {
      print('Compiling ${options[i].join(' ')} $filename');
      CodeLinesResult result = await computeCodeLines(
          options[i], filename, addAnnotations: addAnnotations);
      OutputStructure structure = OutputStructure.parse(result.codeLines);
      computeEntityCodeSources(result, structure);
      output = new AnnotatedOutput(
          filename,
          options[i],
          structure,
          result.coverage.getCoverageReport());
    }
    if (saveTo.containsKey(i)) {
      AnnotatedOutput.saveOutput(output, saveTo[i]);
    }
    outputs.add(output);
  }

  List<DiffBlock> blocks = createDiffBlocks(
      outputs.map((o) => o.structure).toList(),
      sourceFileManager);

  outputDiffView(
      out, outputs, blocks, addAnnotations: addAnnotations);
}

/// Attaches [CodeSource]s to the entities in [structure] using the
/// element-to-offset in [result].
void computeEntityCodeSources(
    CodeLinesResult result, OutputStructure structure) {
  result.elementMap.forEach((int line, Element element) {
    OutputEntity entity = structure.getEntityForLine(line);
    if (entity != null) {
      entity.codeSource = codeSourceFromElement(element);
    }
  });
}

/// The structured output of a compilation.
class AnnotatedOutput {
  final String filename;
  final List<String> options;
  final OutputStructure structure;
  final String coverage;

  AnnotatedOutput(this.filename, this.options, this.structure, this.coverage);

  List<CodeLine> get codeLines => structure.lines;

  Map toJson() {
    return {
      'filename': filename,
      'options': options,
      'structure': structure.toJson(),
      'coverage': coverage,
    };
  }

  static AnnotatedOutput fromJson(Map json) {
    String filename = json['filename'];
    List<String> options = json['options'];
    OutputStructure structure = OutputStructure.fromJson(json['structure']);
    String coverage = json['coverage'];
    return new AnnotatedOutput(filename, options, structure, coverage);
  }

  static AnnotatedOutput loadOutput(filename) {
    AnnotatedOutput output = AnnotatedOutput.fromJson(
        JSON.decode(new File(filename).readAsStringSync()));
    print('Output loaded from $filename');
    return output;
  }

  static void saveOutput(AnnotatedOutput output, String filename) {
    if (filename != null) {
      new File(filename).writeAsStringSync(
          const JsonEncoder.withIndent('  ').convert(output.toJson()));
      print('Output saved in $filename');
    }
  }
}

void outputDiffView(
    String out,
    List<AnnotatedOutput> outputs,
    List<DiffBlock> blocks,
    {bool addAnnotations: true}) {
  assert(outputs[0].filename == outputs[1].filename);
  bool usePre = true;

  StringBuffer sb = new StringBuffer();
  sb.write('''
<html>
<head>
<title>Diff for ${outputs[0].filename}</title>
<style>
.lineNumber {
  font-size: smaller;
  color: #888;
}
.comment {
  font-size: smaller;
  color: #888;
  font-family: initial;
}
.header {
  position: fixed;
  width: 100%;
  background-color: #FFFFFF;
  left: 0px;
  top: 0px;
  height: 42px;
  z-index: 1000;
}
.header-table {
  width: 100%;
  background-color: #400000;
  color: #FFFFFF;
  border-spacing: 0px;
}
.header-column {
  width: 34%;
}
.legend {
  padding: 2px;
}
.table {
  position: absolute;
  left: 0px;
  top: 42px;
  width: 100%;
  border-spacing: 0px;
}
.cell {
  max-width: 500px;
  overflow-y: hidden;
  vertical-align: top;
  border-top: 1px solid #F0F0F0;
  border-left: 1px solid #F0F0F0;
''');
  if (usePre) {
    sb.write('''
  overflow-x: hidden;
  white-space: pre-wrap;
''');
  } else {
    sb.write('''
  overflow-x: hidden;
  padding-left: 100px;
  text-indent: -100px;
''');
  }
  sb.write('''
  font-family: monospace;
  padding: 0px;
}
.corresponding1 {
  background-color: #FFFFE0;
}
.corresponding2 {
  background-color: #EFEFD0;
}
.identical1 {
  background-color: #E0F0E0;
}
.identical2 {
  background-color: #C0E0C0;
}
.line {
  padding-left: 7em;
  text-indent: -7em;
  margin: 0px;
}
.column0 {
}
.column1 {
}
.column2 {
}
</style>
</head>
<body>''');

  sb.write('''
<div class="header">
<table class="header-table"><tr>
<td class="header-column">[${outputs[0].options.join(',')}]</td>
<td class="header-column">[${outputs[1].options.join(',')}]</td>
<td class="header-column">Dart code</td>
</tr></table>
<div class="legend">
  <span class="identical1">&nbsp;&nbsp;&nbsp;</span> 
  <span class="identical2">&nbsp;&nbsp;&nbsp;</span>
  identical blocks
  <span class="corresponding1">&nbsp;&nbsp;&nbsp;</span>
  <span class="corresponding2">&nbsp;&nbsp;&nbsp;</span> 
  corresponding blocks
''');

  if (addAnnotations) {
    sb.write('''
  <span style="$WITH_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
  <span title="'offset with source information' means that source information 
is available for an offset which is expected to have a source location 
attached. This offset has source information as intended.">
  offset with source information</span>
  <span style="$WITHOUT_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
  <span title="'offset without source information' means that _no_ source 
information is available for an offset which was expected to have a source 
location attached. Source information must be found for this offset.">
  offset without source information</span>
  <span style="$ADDITIONAL_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
  <span title="'offset with unneeded source information' means that a source 
location was attached to an offset which was _not_ expected to have a source
location attached. The source location should be removed from this offset.">
  offset with unneeded source information</span>
  <span style="$UNUSED_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
  <span title="'offset with unused source information' means that source 
information is available for an offset which is _not_ expected to have a source
location attached. This source information _could_ be used by a parent AST node
offset that is an 'offset without source information'."> 
  offset with unused source information</span>
''');
  }

  sb.write('''
</div></div>
<table class="table">
''');

  void addCell(String content) {
    sb.write('''
<td class="cell"><pre>
''');
    sb.write(content);
    sb.write('''
</pre></td>
''');
  }

  /// Marker to alternate output colors.
  bool alternating = false;

  List<HtmlPrintContext> printContexts = <HtmlPrintContext>[];
  for (int i = 0; i < 2; i++) {
    int lineNoWidth;
    if (outputs[i].codeLines.isNotEmpty) {
      lineNoWidth = '${outputs[i].codeLines.last.lineNo + 1}'.length;
    }
    printContexts.add(new HtmlPrintContext(lineNoWidth: lineNoWidth));
  }

  for (DiffBlock block in blocks) {
    String className;
    switch (block.kind) {
      case DiffKind.UNMATCHED:
        className = 'cell';
        break;
      case DiffKind.MATCHING:
        className = 'cell corresponding${alternating ? '1' : '2'}';
        alternating = !alternating;
        break;
      case DiffKind.IDENTICAL:
        className = 'cell identical${alternating ? '1' : '2'}';
        alternating = !alternating;
        break;
    }
    sb.write('<tr>');
    for (int index = 0; index < 3; index++) {
      sb.write('''<td class="$className column$index">''');
      List<HtmlPart> lines = block.getColumn(index);
      if (lines.isNotEmpty) {
        for (HtmlPart line in lines) {
          sb.write('<p class="line">');
          if (index < printContexts.length) {
            line.printHtmlOn(sb, printContexts[index]);
          } else {
            line.printHtmlOn(sb, new HtmlPrintContext());
          }
          sb.write('</p>');
        }
      }
      sb.write('''</td>''');
    }
    sb.write('</tr>');
  }

  sb.write('''</tr><tr>''');

  addCell(outputs[0].coverage);
  addCell(outputs[1].coverage);

  sb.write('''
</table>
</body>
</html>
''');

  new File(out).writeAsStringSync(sb.toString());
  print('Diff generated in $out');
}

class CodeLinesResult {
  final List<CodeLine> codeLines;
  final Coverage coverage;
  final Map<int, Element> elementMap;
  final SourceFileManager sourceFileManager;

  CodeLinesResult(this.codeLines, this.coverage,
      this.elementMap, this.sourceFileManager);
}

/// Compute [CodeLine]s and [Coverage] for [filename] using the given [options].
Future<CodeLinesResult> computeCodeLines(
    List<String> options,
    String filename,
    {bool addAnnotations: true}) async {
  SourceMapProcessor processor = new SourceMapProcessor(filename);
  SourceMaps sourceMaps =
      await processor.process(options, perElement: true, forMain: true);

  const int WITH_SOURCE_INFO = 0;
  const int WITHOUT_SOURCE_INFO = 1;
  const int ADDITIONAL_SOURCE_INFO = 2;
  const int UNUSED_SOURCE_INFO = 3;

  SourceMapInfo info = sourceMaps.mainSourceMapInfo;

  List<CodeLine> codeLines;
  Coverage coverage = new Coverage();
  List<Annotation> annotations = <Annotation>[];

  void addAnnotation(int id, int offset, String title) {
    annotations.add(new Annotation(id, offset, title));
  }

  String code = info.code;
  TraceGraph graph = createTraceGraph(info, coverage);
  if (addAnnotations) {
    Set<js.Node> mappedNodes = new Set<js.Node>();

    void addSourceLocations(
        int kind, int offset, List<SourceLocation> locations, String prefix) {

      addAnnotation(kind, offset,
          '${prefix}${locations
              .where((l) => l != null)
              .map((l) => l.shortText)
              .join('\n')}');
    }

    bool addSourceLocationsForNode(int kind, js.Node node, String prefix) {
      Map<int, List<SourceLocation>> locations = info.nodeMap[node];
      if (locations == null || locations.isEmpty) {
        return false;
      }
      locations.forEach(
          (int offset, List<SourceLocation> locations) {
        addSourceLocations(kind, offset, locations,
            '${prefix}\n${truncate(nodeToString(node), 80)}\n');
      });
      mappedNodes.add(node);
      return true;
    }


    for (TraceStep step in graph.steps) {
      String title = '${step.id}:${step.kind}:${step.offset}';
      if (!addSourceLocationsForNode(WITH_SOURCE_INFO, step.node, title)) {
        int offset;
        if (options.contains(USE_NEW_SOURCE_INFO)) {
          offset = step.offset.subexpressionOffset;
        } else {
          offset = info.jsCodePositions[step.node].startPosition;
        }
        if (offset != null) {
          addAnnotation(WITHOUT_SOURCE_INFO, offset, title);
        }
      }
    }
    for (js.Node node in info.nodeMap.nodes) {
      if (!mappedNodes.contains(node)) {
        addSourceLocationsForNode(ADDITIONAL_SOURCE_INFO, node, '');
      }
    }
    SourceLocationCollector collector = new SourceLocationCollector();
    info.node.accept(collector);
    collector.sourceLocations.forEach(
        (js.Node node, List<SourceLocation> locations) {
      if (!mappedNodes.contains(node)) {
        int offset = info.jsCodePositions[node].startPosition;
        addSourceLocations(UNUSED_SOURCE_INFO, offset, locations, '');
      }
    });
  }

  StringSourceFile sourceFile = new StringSourceFile.fromName(filename, code);
  Map<int, Element> elementMap = <int, Element>{};
  sourceMaps.elementSourceMapInfos.forEach(
      (Element element, SourceMapInfo info) {
    CodePosition position = info.jsCodePositions[info.node];
    elementMap[sourceFile.getLine(position.startPosition)] = element;
  });

  codeLines = convertAnnotatedCodeToCodeLines(
      code,
      annotations,
      colorScheme: new CustomColorScheme(
        single: (int id) {
          if (id == WITH_SOURCE_INFO) {
            return WITH_SOURCE_INFO_STYLE;
          } else if (id == ADDITIONAL_SOURCE_INFO) {
            return ADDITIONAL_SOURCE_INFO_STYLE;
          } else if (id == UNUSED_SOURCE_INFO) {
            return UNUSED_SOURCE_INFO_STYLE;
          }
          return WITHOUT_SOURCE_INFO_STYLE;
        },
        multi: (List ids) {
          if (ids.contains(WITH_SOURCE_INFO)) {
            return WITH_SOURCE_INFO_STYLE;
          } else if (ids.contains(ADDITIONAL_SOURCE_INFO)) {
            return ADDITIONAL_SOURCE_INFO_STYLE;
          } else if (ids.contains(UNUSED_SOURCE_INFO)) {
            return UNUSED_SOURCE_INFO_STYLE;
          }
          return WITHOUT_SOURCE_INFO_STYLE;
        }
      ));
  return new CodeLinesResult(codeLines, coverage, elementMap,
      sourceMaps.sourceFileManager);
}

/// Visitor that computes a map from [js.Node]s to all attached source
/// locations.
class SourceLocationCollector extends js.BaseVisitor {
  Map<js.Node, List<SourceLocation>> sourceLocations =
      <js.Node, List<SourceLocation>>{};

  @override
  visitNode(js.Node node) {
    SourceInformation sourceInformation = node.sourceInformation;
    if (sourceInformation != null) {
      sourceLocations[node] = sourceInformation.sourceLocations;
    }
    node.visitChildren(this);
  }
}

/// Compute a [CodeSource] for source span of [element].
CodeSource codeSourceFromElement(Element element) {
  CodeKind kind;
  Uri uri;
  String name;
  int begin;
  int end;
  if (element.isLibrary) {
    LibraryElement library = element;
    kind = CodeKind.LIBRARY;
    name = library.libraryOrScriptName;
    uri = library.entryCompilationUnit.script.resourceUri;
  } else if (element.isClass) {
    kind = CodeKind.CLASS;
    name = element.name;
    uri = element.compilationUnit.script.resourceUri;
  } else {
    AstElement astElement = element.implementation;
    kind = CodeKind.MEMBER;
    uri = astElement.compilationUnit.script.resourceUri;
    name = computeElementNameForSourceMaps(astElement);
    if (astElement.hasNode) {
      begin = astElement.node.getBeginToken().charOffset;
      end = astElement.node.getEndToken().charEnd;
    }
  }
  return new CodeSource(kind, uri, name, begin, end);
}