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

import 'dart:html';
import 'dart:convert';
import 'dart:async';
import 'package:source_maps/source_maps.dart';

Element targetFileName = querySelector("#target_filename");
Element sourceFileName = querySelector("#source_filename");
DivElement generatedOutput = querySelector("#generated_output");
DivElement selectedSource = querySelector("#selected_source");
DivElement selectedOutputSpan = querySelector("#current_span");
DivElement decodedMap = querySelector("#decoded_map");
DivElement originalMap = querySelector("#original_map");

Map<TargetEntry, List<SpanElement>> targetEntryMap = {};
List<SpanElement> highlightedMapEntry = null;
List<String> target;
SingleMapping sourceMap;

void adjustDivHeightsToWindow() {
  generatedOutput.style.height = "${window.innerHeight / 3 - 50}px";
  selectedSource.style.height = "${window.innerHeight / 3 - 50}px";
  decodedMap.style.height = "${window.innerHeight / 3 - 50}px";
  originalMap.style.height = "${window.innerHeight / 3 - 50}px";
}

Future getMap() {
  Completer c = new Completer();
  HttpRequest httpRequest = new HttpRequest();
  httpRequest
    ..open('GET', '/map')
    ..onLoadEnd.listen((_) => c.complete(httpRequest.responseText))
    ..send('');
  return c.future;
}

Future fetchFile(String path) {
  Completer c = new Completer();
  HttpRequest httpRequest = new HttpRequest();
  sourceFileName.text = path;
  httpRequest
    ..open('GET', path)
    ..onLoadEnd.listen((_) => c.complete(httpRequest.responseText))
    ..send('');
  return c.future;
}

displaySource(String filename, List<String> source, TargetEntry entry) {
  int line = entry.sourceLine;
  int column = entry.sourceColumn;
  selectedSource.children.clear();
  SpanElement marker = new SpanElement()
    ..className = "marker"
    ..appendText("*");
  for (int pos = 0; pos < source.length; pos++) {
    String l = source[pos];
    if (pos != line) {
      selectedSource.children.add(l.isEmpty ? new BRElement() : new DivElement()
        ..appendText(l));
    } else {
      selectedSource.children.add(new DivElement()
        ..appendText(l.substring(0, column))
        ..children.add(marker)
        ..appendText(l.substring(column)));
    }
  }
  sourceFileName.text = filename;
  marker.scrollIntoView();
}

void highlightSelectedSpan(TargetEntry entry, TargetLineEntry lineEntry) {
  selectedOutputSpan.children.clear();
  String spanEndCol;
  TargetEntry spanEnd;
  bool nextEntryIsSpanEnd = false;
  for (TargetEntry e in lineEntry.entries) {
    if (nextEntryIsSpanEnd) {
      spanEnd = e;
      break;
    }
    if (e == entry) {
      nextEntryIsSpanEnd = true;
    }
  }
  if (spanEnd == null) {
    spanEndCol = '${target[lineEntry.line].length} (EOL).';
  } else {
    spanEndCol = '${spanEnd.column}.';
  }

  String targetSpan =
      'Target:  Line ${lineEntry.line} Col. ${entry.column} - $spanEndCol';

  if (entry.sourceUrlId == null) {
    targetSpan += ' Source: unknown';
    selectedOutputSpan.children.add(getTextElement(targetSpan));
    return;
  }

  String source = sourceMap.urls[entry.sourceUrlId];
  String sourceName = source.substring(source.lastIndexOf('/') + 1);
  String sourcePoint =
      'Source: Line ${entry.sourceLine} Col. ${entry.sourceColumn}';
  sourcePoint += entry.sourceNameId == null
      ? ''
      : ' (${sourceMap.names[entry.sourceNameId]})';
  sourcePoint += ' in $sourceName';
  selectedOutputSpan.children.add(getTextElement(targetSpan));
  selectedOutputSpan.children.add(new BRElement());
  selectedOutputSpan.children.add(getTextElement(sourcePoint));

  if (highlightedMapEntry != null) {
    highlightedMapEntry[0].style.background = 'white';
    highlightedMapEntry[1].style.background = 'white';
  }

  String highlightColor = "#99ff99";
  highlightedMapEntry = targetEntryMap[entry];
  highlightedMapEntry[0]
    ..scrollIntoView()
    ..style.backgroundColor = highlightColor;
  highlightedMapEntry[1]
    ..scrollIntoView()
    ..style.backgroundColor = highlightColor;
  highlightedMapEntry[1].onMouseOver.listen((e) {
    selectedOutputSpan.style.zIndex = "2";
    selectedOutputSpan.style.visibility = "visible";
    selectedOutputSpan.style.top = "${decodedMap.offsetTo(document.body).y +
                                      decodedMap.clientHeight - 20}px";
    selectedOutputSpan.style.left = "${decodedMap.offsetTo(document.body).x}px";
    selectedOutputSpan.style.width = "${decodedMap.clientWidth}px";
  });

  highlightedMapEntry[1].onMouseOut.listen((e) {
    selectedOutputSpan.style.visibility = "hidden";
  });

  adjustDivHeightsToWindow();
}

void loadSource(TargetEntry entry) {
  if (entry.sourceUrlId == null) {
    return;
  }

  String source = sourceMap.urls[entry.sourceUrlId];
  fetchFile(
          new Uri(path: "/file", queryParameters: {"path": source}).toString())
      .then((text) => displaySource(source, text.split("\n"), entry));
  selectedSource.text = "loading";
}

SpanElement createSpan(
    String content, TargetEntry entry, TargetLineEntry lineEntry) {
  return new SpanElement()
    ..addEventListener('click', (e) {
      loadSource(entry);
      highlightSelectedSpan(entry, lineEntry);
    }, false)
    ..className = "range${entry.sourceUrlId % 4}"
    ..appendText(content);
}

Element getLineNumberElement(int line) {
  SpanElement result = new SpanElement();
  result.style.fontFamily = "Courier";
  result.style.fontSize = "10pt";
  result.appendText("${line} ");
  return result;
}

Element getTextElement(String text) {
  SpanElement result = new SpanElement();
  result.text = text;
  return result;
}

addTargetLine(int lineNumber, String content, TargetLineEntry lineEntry) {
  if (content.isEmpty) {
    generatedOutput.children
        .add(new DivElement()..children.add(getLineNumberElement(lineNumber)));
    return;
  }
  if (lineEntry == null) {
    generatedOutput.children.add(new DivElement()
      ..children.add(getLineNumberElement(lineNumber))
      ..children.add(getTextElement(content)));
    return;
  }
  DivElement div = new DivElement();
  div.children.add(getLineNumberElement(lineNumber));

  int pos = 0;
  TargetEntry previous = null;
  for (TargetEntry next in lineEntry.entries) {
    if (previous == null) {
      if (pos < next.column) {
        div.appendText(content.substring(pos, next.column));
      }
      if (content.length == next.column) {
        div.children.add(createSpan(" ", next, lineEntry));
      }
    } else {
      if (next.column <= content.length) {
        String token = content.substring(pos, next.column);
        div.children.add(createSpan(token, previous, lineEntry));
      }
      if (content.length == next.column) {
        div.children.add(createSpan(" ", next, lineEntry));
      }
    }
    pos = next.column;
    previous = next;
  }
  String token = content.substring(pos);
  if (previous == null) {
    div.appendText(token);
  } else {
    div..children.add(createSpan(token, previous, lineEntry));
  }
  generatedOutput.children.add(div);
}

// Display the target source in the HTML.
void displayTargetSource() {
  List<TargetLineEntry> targetLines = sourceMap.lines;
  int linesIndex = 0;
  for (int line = 0; line < target.length; line++) {
    TargetLineEntry entry = null;
    if (linesIndex < targetLines.length &&
        targetLines[linesIndex].line == line) {
      entry = targetLines[linesIndex];
      linesIndex++;
    }
    if (entry != null) {
      addTargetLine(line, target[line], entry);
    } else {
      addTargetLine(line, target[line], null);
    }
  }
}

String getMappedData(String mapFileContent) {
  // Source map contains mapping information in this format:
  // "mappings": "A;A,yC;"
  List<String> mapEntry = mapFileContent.split('mappings');
  return mapEntry[mapEntry.length - 1].split('"')[2];
}

SpanElement createMapSpan(String segment) {
  return new SpanElement()..text = segment;
}

SpanElement createDecodedMapSpan(TargetEntry entry) {
  return new SpanElement()
    ..text = '(${entry.column}, ${entry.sourceUrlId},'
        ' ${entry.sourceLine},'
        ' ${entry.sourceColumn})';
}

displayMap(String mapFileContent) {
  String mappedData = getMappedData(mapFileContent);
  int sourceMapLine = 0;
  for (String group in mappedData.split(';')) {
    if (group.length == 0) continue;

    List<String> segments = [];
    if (!group.contains(',')) {
      segments.add(group);
    } else {
      segments = group.split(',');
    }

    TargetLineEntry targetLineEntry = sourceMap.lines[sourceMapLine];
    decodedMap.children.add(getLineNumberElement(targetLineEntry.line));
    originalMap.children.add(getLineNumberElement(targetLineEntry.line));
    bool first = true;
    int entryNumber = 0;
    for (String segment in segments) {
      TargetEntry entry = targetLineEntry.entries[entryNumber];
      SpanElement orignalMapSpan = createMapSpan(segment);
      SpanElement decodedMapSpan = createDecodedMapSpan(entry);
      if (first) {
        first = false;
      } else {
        originalMap.children.add(getTextElement(', '));
        decodedMap.children.add(getTextElement(', '));
      }
      originalMap.children.add(orignalMapSpan);
      decodedMap.children.add(decodedMapSpan);
      ++entryNumber;
      targetEntryMap.putIfAbsent(entry, () => [orignalMapSpan, decodedMapSpan]);
    }
    originalMap.children.add(new BRElement());
    decodedMap.children.add(new BRElement());
    ++sourceMapLine;
  }
}

void main() {
  Future load(String q) => fetchFile(
      new Uri(path: "/file", queryParameters: {"path": q}).toString());

  getMap().then((mapFileName) {
    load(mapFileName).then((mapFileContent) {
      sourceMap = new SingleMapping.fromJson(jsonDecode(mapFileContent));
      displayMap(mapFileContent);
      targetFileName.text = sourceMap.targetUrl;
      load(targetFileName.text).then((targetFileContent) {
        target = targetFileContent.split('\n');
        displayTargetSource();
        adjustDivHeightsToWindow();
      });
    });
  });

  sourceFileName.text = "<source not selected>";
}
