import 'dart:convert' show jsonDecode;
import 'dart:io';

import 'package:_fe_analyzer_shared/src/testing/annotated_code_helper.dart';
import 'package:collection/collection.dart' show IterableNullableExtension;
import 'package:dart2js_tools/src/util.dart';
import 'package:expect/minitest.dart';
import 'package:path/path.dart' as path;
import 'package:source_maps/source_maps.dart';

/// Runs D8 and steps as the AnnotatedCode dictates.
///
/// Note that the compiled javascript is expected to be called "js.js" inside
/// the outputPath directory. It is also expected that there is a "js.js.map"
/// file. It is furthermore expected that the js has been compiled from a file
/// in the same folder called test.dart.
ProcessResult runD8AndStep(String outputPath, String testFileName,
    AnnotatedCode code, List<String> scriptD8Command) {
  var outputFile = path.join(outputPath, 'js.js');
  var sourcemapText = File('$outputFile.map').readAsStringSync();
  SingleMapping sourceMap = parseSingleMapping(jsonDecode(sourcemapText));

  Set<int?> mappedToLines = sourceMap.lines
      .map((entry) => entry.entries.map((entry) => entry.sourceLine).toSet())
      .fold(<int?>{}, (prev, e) => prev..addAll(e));

  for (Annotation annotation
      in code.annotations.where((a) => a.text.trim() == 'nm')) {
    if (mappedToLines.contains(annotation.lineNo - 1)) {
      fail('Was not allowed to have a mapping to line '
          '${annotation.lineNo}, but did.\n'
          'Sourcemap looks like this (note 0-indexed):\n'
          '${sourceMap.debugString}');
    }
  }

  List<String?> breakpoints = [];
  // Annotations are 1-based, js breakpoints are 0-based.
  for (Annotation breakAt
      in code.annotations.where((a) => a.text.trim() == 'bl')) {
    breakpoints
        .add(_getJsBreakpointLine(testFileName, sourceMap, breakAt.lineNo - 1));
  }
  for (Annotation breakAt
      in code.annotations.where((a) => a.text.trim().startsWith('bc:'))) {
    breakpoints.add(_getJsBreakpointLineAndColumn(
        testFileName, sourceMap, breakAt.lineNo - 1, breakAt.columnNo - 1));
  }

  File inspectorFile = File.fromUri(
      sdkRoot!.uri.resolve('pkg/sourcemap_testing/lib/src/js/inspector.js'));
  if (!inspectorFile.existsSync()) throw "Couldn't find 'inspector.js'";
  var outInspectorPath = path.join(outputPath, 'inspector.js');
  inspectorFile.copySync(outInspectorPath);
  String debugAction = 'Debugger.stepInto';
  if (code.annotations.any((a) => a.text.trim() == 'Debugger:stepOver')) {
    debugAction = 'Debugger.stepOver';
  }
  return _runD8(outInspectorPath, scriptD8Command, debugAction, breakpoints);
}

/// Translates the D8 js steps and checks against expectations.
///
/// Note that the compiled javascript is expected to be called "js.js" inside
/// the outputPath directory. It is also expected that there is a "js.js.map"
/// file. It is furthermore expected that the js has been compiled from a file
/// in the same folder called test.dart.
void checkD8Steps(String outputPath, List<String> d8Output, AnnotatedCode code,
    {bool debug = false}) {
  var outputFilename = 'js.js';
  var outputFile = path.join(outputPath, outputFilename);
  var sourcemapText = File('$outputFile.map').readAsStringSync();
  SingleMapping sourceMap = parseSingleMapping(jsonDecode(sourcemapText));

  List<List<_DartStackTraceDataEntry>> result =
      _extractStackTraces(d8Output, sourceMap, outputFilename);

  List<_DartStackTraceDataEntry> trace =
      result.map((entry) => entry.first).toList();
  if (debug) _debugPrint(trace, outputPath);

  List<String> recordStops =
      trace.where((entry) => !entry.isError).map((entry) => '$entry').toList();

  Set<int> recordStopLines =
      trace.where((entry) => !entry.isError).map((entry) => entry.line).toSet();
  Set<String> recordStopLineColumns = trace
      .where((entry) => !entry.isError)
      .map((entry) => '${entry.line}:${entry.column}')
      .toSet();

  List<String> expectedStops = [];
  for (Annotation annotation in code.annotations.where((annotation) =>
      annotation.text.trim().startsWith('s:') ||
      annotation.text.trim().startsWith('sl:') ||
      annotation.text.trim().startsWith('bc:'))) {
    String text = annotation.text.trim();
    int stopNum = int.parse(text.substring(text.indexOf(':') + 1));
    if (expectedStops.length < stopNum) expectedStops.length = stopNum;
    if (text.startsWith('sl:')) {
      expectedStops[stopNum - 1] = 'test.dart:${annotation.lineNo}:';
    } else {
      expectedStops[stopNum - 1] =
          'test.dart:${annotation.lineNo}:${annotation.columnNo}:';
    }
  }

  List<List<String>?> noBreaksStart = [];
  List<List<String>?> noBreaksEnd = [];
  for (Annotation annotation in code.annotations
      .where((annotation) => annotation.text.trim().startsWith('nbb:'))) {
    String text = annotation.text.trim();
    var split = text.split(':');
    int stopNum1 = int.parse(split[1]);
    int stopNum2 = int.parse(split[2]);
    if (noBreaksStart.length <= stopNum1) noBreaksStart.length = stopNum1 + 1;
    (noBreaksStart[stopNum1] ??= []).add('test.dart:${annotation.lineNo}:');
    if (noBreaksEnd.length <= stopNum2) noBreaksEnd.length = stopNum2 + 1;
    (noBreaksEnd[stopNum2] ??= []).add('test.dart:${annotation.lineNo}:');
  }

  _checkRecordedStops(
      recordStops, expectedStops, noBreaksStart, noBreaksEnd, debug);

  for (Annotation annotation in code.annotations
      .where((annotation) => annotation.text.trim() == 'nb')) {
    // Check that we didn't break where we're not allowed to.
    if (recordStopLines.contains(annotation.lineNo)) {
      fail('Was not allowed to stop on line ${annotation.lineNo}, but did!'
          '  Actual line stops: $recordStopLines${_debugHint(debug)}');
    }
  }
  for (Annotation annotation in code.annotations
      .where((annotation) => annotation.text.trim() == 'nbc')) {
    // Check that we didn't break where we're not allowed to.
    if (recordStopLineColumns
        .contains('${annotation.lineNo}:${annotation.columnNo}')) {
      fail('Was not allowed to stop on line ${annotation.lineNo} '
          'column ${annotation.columnNo}, but did!'
          '  Actual line stops: $recordStopLineColumns${_debugHint(debug)}');
    }
  }

  if (code.annotations.any((a) => a.text.trim() == 'fail')) {
    fail("Test contains 'fail' annotation.");
  }
}

void _checkRecordedStops(
    List<String> recordStops,
    List<String> expectedStops,
    List<List<String>?> noBreaksStart,
    List<List<String>?> noBreaksEnd,
    bool debug) {
  // We want to find all expected lines in recorded lines in order, but allow
  // more in between in the recorded lines.
  // noBreaksStart and noBreaksStart gives instructions on what's *NOT* allowed
  // to be between those points though.

  int expectedIndex = 0;
  Set<String> aliveNoBreaks = {};
  if (noBreaksStart.isNotEmpty && noBreaksStart[0] != null) {
    aliveNoBreaks.addAll(noBreaksStart[0]!);
  }
  int stopNumber = 0;
  for (String recorded in recordStops) {
    stopNumber++;
    if (expectedIndex == expectedStops.length) break;
    if ('$recorded:'.contains(expectedStops[expectedIndex])) {
      ++expectedIndex;
      if (noBreaksStart.length > expectedIndex &&
          noBreaksStart[expectedIndex] != null) {
        aliveNoBreaks.addAll(noBreaksStart[expectedIndex]!);
      }
      if (noBreaksEnd.length > expectedIndex &&
          noBreaksEnd[expectedIndex] != null) {
        aliveNoBreaks.removeAll(noBreaksEnd[expectedIndex]!);
      }
    } else {
      if (debug) {
        // One of the most helpful debugging tools is to see stops that weren't
        // matched. The most common failure is we didn't match one particular
        // stop location (e.g. because of the column). This gets reported
        // as an aliveNoBreaks failure (if the test is using no-breaks like
        // `nbb`) or it's reported as "stops don't match" message.
        //
        // Both failures are difficult to debug without seeing the stops that
        // didn't match. No breaks failures are misleading (the problem isn't
        // an incorrect break, but we missed a stop, so the aliveNoBreaks is
        // wrong), and the normal failure list dumps the entire stop list,
        // making it difficult to see where the mismatch was.
        //
        // Also we add 1 to expectedIndex, because the stop annotations are
        // 1-based in the source files (e.g. `/*s:1*/` is expectedIndex 0)
        print("Skipping stop `$recorded` that didn't match expected stop "
            '${expectedIndex + 1} `${expectedStops[expectedIndex]}`');
      }
      if (aliveNoBreaks
          .contains("${(recorded.split(":")..removeLast()).join(":")}:")) {
        fail("Break '$recorded' was found when it wasn't allowed "
            '(js step $stopNumber, after stop ${expectedIndex + 1}). '
            'This can happen when an expected stop was not matched'
            '${_debugHint(debug)}.');
      }
    }
  }
  if (expectedIndex != expectedStops.length) {
    // Didn't find everything.
    fail('Expected to find $expectedStops but found $recordStops'
        '${_debugHint(debug)}');
  }
}

/// If we're not in debug mode, this returns a message string with information
/// about how to enable debug mode in the test runner.
String _debugHint(bool debug) {
  if (debug) return ''; // already in debug mode
  return ' (pass -Ddebug=1 to the test runner to see debug information)';
}

void _debugPrint(List<_DartStackTraceDataEntry> trace, String outputPath) {
  StringBuffer sb = StringBuffer();
  var jsFile =
      File(path.join(outputPath, 'js.js')).readAsStringSync().split('\n');
  var dartFile =
      File(path.join(outputPath, 'test.dart')).readAsStringSync().split('\n');

  List<String> getSnippet(List<String> data, int line, int column) {
    List<String> result = List<String>.filled(5, '');
    if (line < 0 || column < 0) return result;

    for (int i = 0; i < 5; ++i) {
      int j = line - 2 + i;
      if (j < 0 || j >= data.length) continue;
      result[i] = data[j];
    }
    if (result[2].length >= column) {
      var before = result[2].substring(0, column);
      var after = result[2].substring(column);
      result[2] = '$before/*STOP*/$after';
    }
    return result;
  }

  List<String> sideBySide(List<String> a, List<String> b, int columns) {
    List<String> result = List<String>.filled(a.length, '');
    for (int i = 0; i < a.length; ++i) {
      String left = a[i].padRight(columns).substring(0, columns);
      String right = b[i].padRight(columns).substring(0, columns);
      result[i] = '$left  |  $right';
    }
    return result;
  }

  for (int i = 0; i < trace.length; ++i) {
    sb.write('\n\nStop #${i + 1}\n\n');
    if (trace[i].isError && trace[i].jsLine < 0) {
      sb.write('${trace[i].errorString}\n');
      continue;
    }
    var jsSnippet = getSnippet(jsFile, trace[i].jsLine, trace[i].jsColumn);
    var dartSnippet =
        getSnippet(dartFile, trace[i].line - 1, trace[i].column - 1);
    var view = sideBySide(jsSnippet, dartSnippet, 50);
    sb.writeAll(view, '\n');
  }

  print(sb.toString());
}

List<List<_DartStackTraceDataEntry>> _extractStackTraces(
    List<String> lines, SingleMapping sourceMap, String outputFilename) {
  List<List<_DartStackTraceDataEntry>> result = [];
  bool inStackTrace = false;
  List<String> currentStackTrace = <String>[];
  for (var line in lines) {
    if (line.trim() == '--- Debugger stacktrace start ---') {
      inStackTrace = true;
    } else if (line.trim() == '--- Debugger stacktrace end ---') {
      result.add(
          _extractStackTrace(currentStackTrace, sourceMap, outputFilename));
      currentStackTrace.clear();
      inStackTrace = false;
    } else if (inStackTrace) {
      currentStackTrace.add(line.trim());
    }
  }
  return result;
}

List<_DartStackTraceDataEntry> _extractStackTrace(
    List<String> js, SingleMapping sourceMap, String wantedFile) {
  List<_DartStackTraceDataEntry> result = [];
  for (String line in js) {
    if (!line.contains('$wantedFile:')) {
      result.add(_DartStackTraceDataEntry.error("Not correct file @ '$line'"));
      continue;
    }
    Iterable<Match> ms = RegExp(r'(\d+):(\d+)').allMatches(line);
    if (ms.isEmpty) {
      result.add(_DartStackTraceDataEntry.error(
          "Line and column not found for '$line'"));
      continue;
    }
    Match m = ms.first;
    int l = int.parse(m.group(1)!);
    int c = int.parse(m.group(2)!);
    SourceMapSpan? span = _getColumnOrPredecessor(sourceMap, l, c);
    if (span?.start == null) {
      result.add(_DartStackTraceDataEntry.errorWithJsPosition(
          "Source map not found for '$line'", l, c));
      continue;
    }
    var file = span!.sourceUrl?.pathSegments.last ?? '(unknown file)';
    result.add(_DartStackTraceDataEntry(
        file, span.start.line + 1, span.start.column + 1, l, c));
  }
  return result;
}

SourceMapSpan? _getColumnOrPredecessor(
    SingleMapping sourceMap, int line, int column) {
  SourceMapSpan? span = sourceMap.spanFor(line, column);
  if (span == null && line > 0) {
    span = sourceMap.spanFor(line - 1, 999999);
  }
  return span;
}

class _DartStackTraceDataEntry {
  final String? file;
  final int line;
  final int column;
  final String? errorString;
  final int jsLine;
  final int jsColumn;

  _DartStackTraceDataEntry(
      this.file, this.line, this.column, this.jsLine, this.jsColumn)
      : errorString = null;
  _DartStackTraceDataEntry.error(this.errorString)
      : file = null,
        line = -1,
        column = -1,
        jsLine = -1,
        jsColumn = -1;
  _DartStackTraceDataEntry.errorWithJsPosition(
      this.errorString, this.jsLine, this.jsColumn)
      : file = null,
        line = -1,
        column = -1;

  bool get isError => errorString != null;

  @override
  String toString() => isError ? errorString! : '$file:$line:$column';
}

class _PointMapping {
  final int fromLine;
  final int fromColumn;
  final int toLine;
  final int toColumn;

  _PointMapping(this.fromLine, this.fromColumn, this.toLine, this.toColumn);
}

/// Input and output is expected to be 0-based.
///
/// The "magic 4" below is taken from
/// https://github.com/ChromeDevTools/devtools-frontend/blob/fa18d70a995f06cb73365b2e5b8ae974cf60bd3a/front_end/sources/JavaScriptSourceFrame.js#L1520-L1523
String? _getJsBreakpointLine(
    String testFileName, SingleMapping sourceMap, int breakOnLine) {
  List<_PointMapping> mappingsOnLines = [];
  for (var line in sourceMap.lines) {
    for (var entry in line.entries) {
      final sourceLine = entry.sourceLine;
      if (sourceLine == null) continue;
      final sourceColumn = entry.sourceColumn!;
      final sourceUrlId = entry.sourceUrlId;
      if (sourceLine >= breakOnLine &&
          sourceLine < breakOnLine + 4 &&
          sourceUrlId != null &&
          sourceMap.urls[sourceUrlId] == testFileName) {
        mappingsOnLines.add(
            _PointMapping(sourceLine, sourceColumn, line.line, entry.column));
      }
    }
  }

  if (mappingsOnLines.isEmpty) return null;

  mappingsOnLines.sort((a, b) {
    if (a.fromLine != b.fromLine) return a.fromLine - b.fromLine;
    if (a.fromColumn != b.fromColumn) return a.fromColumn - b.fromColumn;
    if (a.toLine != b.toLine) return a.toLine - b.toLine;
    return a.toColumn - b.toColumn;
  });
  _PointMapping first = mappingsOnLines.first;
  mappingsOnLines.retainWhere((p) => p.toLine >= first.toLine);

  _PointMapping last = mappingsOnLines.last;
  return '${first.toLine}:${first.toColumn}:${last.toLine}:${first.toColumn}';
}

/// Input and output is expected to be 0-based.
String? _getJsBreakpointLineAndColumn(String testFileName,
    SingleMapping sourceMap, int breakOnLine, int breakOnColumn) {
  for (var line in sourceMap.lines) {
    for (var entry in line.entries) {
      if (entry.sourceLine == breakOnLine &&
          entry.sourceColumn == breakOnColumn &&
          entry.sourceUrlId != null &&
          sourceMap.urls[entry.sourceUrlId!] == testFileName) {
        return '${line.line}:${entry.column}';
      }
    }
  }
  return null;
}

ProcessResult _runD8(String outInspectorPath, List<String> scriptD8Command,
    String debugAction, List<String?> breakpoints) {
  var outInspectorPathRelative = path.relative(outInspectorPath);
  ProcessResult runResult = Process.runSync(d8Executable, [
    '--enable-inspector',
    outInspectorPathRelative,
    ...scriptD8Command,
    '--',
    debugAction,
    ...breakpoints.whereNotNull()
  ]);
  if (runResult.exitCode != 0) {
    print(runResult.stderr);
    print(runResult.stdout);
    throw 'Exit code: ${runResult.exitCode} from d8';
  }
  return runResult;
}

File? _cachedD8File;
Directory? _cachedSdkRoot;
File getD8File() {
  File attemptFileFromDir(Directory dir) {
    if (Platform.isWindows) {
      return File('${dir.path}${Platform.pathSeparator}d8/windows/d8.exe');
    } else if (Platform.isLinux) {
      return File('${dir.path}${Platform.pathSeparator}d8/linux/d8');
    } else if (Platform.isMacOS) {
      return File('${dir.path}${Platform.pathSeparator}d8/macos/d8');
    }
    throw UnsupportedError('Unsupported platform.');
  }

  File search() {
    Directory dir = File.fromUri(Platform.script).parent;
    while (dir.path.length > 1) {
      for (var entry in dir.listSync()) {
        if (entry is! Directory) continue;
        if (entry.path.endsWith('third_party')) {
          List<String> segments = entry.uri.pathSegments;
          if (segments[segments.length - 2] == 'third_party') {
            File possibleD8 = attemptFileFromDir(entry);
            if (possibleD8.existsSync()) {
              _cachedSdkRoot = dir;
              return possibleD8;
            }
          }
        }
      }
      dir = dir.parent;
    }

    throw 'Cannot find D8 directory.';
  }

  return _cachedD8File ??= search();
}

Directory? get sdkRoot {
  getD8File();
  return _cachedSdkRoot;
}

String get d8Executable {
  return getD8File().path;
}
