// 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.

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

import 'package:_fe_analyzer_shared/src/testing/annotated_code_helper.dart';
import 'package:dart2js_tools/src/dart2js_mapping.dart';
import 'package:dart2js_tools/src/util.dart';
import 'package:expect/expect.dart';
import 'package:source_maps/source_maps.dart';
import 'package:source_maps/src/utils.dart';
import 'package:source_span/source_span.dart';

const String inputFileName = 'input.dart';

class Test {
  final String code;
  final Map<String, Expectations> expectationMap;

  Test(this.code, this.expectationMap);
}

class Expectations {
  final List<StackTraceLine> expectedLines;
  final List<StackTraceLine> unexpectedLines;

  Expectations(this.expectedLines, this.unexpectedLines);
}

/// Convert the annotated [code] to a [Test] object using [configs] to split
/// the annotations by prefix.
Test processTestCode(String code, Iterable<String> configs) {
  AnnotatedCode annotatedCode =
      AnnotatedCode.fromText(code, commentStart, commentEnd);

  Map<String, Expectations> expectationMap = <String, Expectations>{};

  splitByPrefixes(annotatedCode, configs)
      .forEach((String config, AnnotatedCode annotatedCode) {
    Map<int, StackTraceLine> stackTraceMap = <int, StackTraceLine>{};
    List<StackTraceLine> unexpectedLines = <StackTraceLine>[];

    for (Annotation annotation in annotatedCode.annotations) {
      String text = annotation.text;
      int colonIndex = text.indexOf(':');
      String indexText = text.substring(0, colonIndex);
      String methodName = text.substring(colonIndex + 1);
      StackTraceLine stackTraceLine = StackTraceLine(
          methodName, inputFileName, annotation.lineNo, annotation.columnNo);
      if (indexText == '') {
        unexpectedLines.add(stackTraceLine);
      } else {
        int stackTraceIndex = int.parse(indexText);
        assert(!stackTraceMap.containsKey(stackTraceIndex));
        stackTraceMap[stackTraceIndex] = stackTraceLine;
      }
    }

    List<StackTraceLine> expectedLines = [];
    for (int stackTraceIndex
        in (stackTraceMap.keys.toList()..sort()).reversed) {
      expectedLines.add(stackTraceMap[stackTraceIndex]!);
    }
    expectationMap[config] = Expectations(expectedLines, unexpectedLines);
  });

  return Test(annotatedCode.sourceCode, expectationMap);
}

/// Compile function used in [testStackTrace]. [input] is the name of the input
/// Dart file and [output] is the name of the generated JavaScript file. The
/// function returns `true` if the compilation succeeded.
typedef CompileFunc = Future<bool> Function(String, String);

List<String> emptyPreamble(input, output) => const <String>[];
String? identityConverter(String? name) => name;

/// Tests the stack trace of [test] using the expectations for [config].
///
/// The [compile] function is called to compile the Dart code in [test] to
/// JavaScript.
///
/// The [jsPreambles] contains the path of additional JavaScript files needed
/// to run the generated JavaScript file.
///
/// The [beforeExceptions] lines are allowed before the intended stack trace.
/// The [afterExceptions] lines are allowed after the intended stack trace.
///
/// If [printJs] is `true`, the generated JavaScript code is print to the
/// console. If [writeJs] is `true` the generated JavaScript code and the
/// generated source map are saved in the current working directory (as 'out.js'
/// and 'out.js.map', respectively).
///
/// If forcedTmpDir is given that directory is used as the out directory and
/// will not be cleaned up. Note that if *not* giving a temporary directory and
/// the test fails the directory will not be cleaned up.
Future testStackTrace(Test test, String config, CompileFunc compile,
    {bool printJs = false,
    bool writeJs = false,
    bool verbose = false,
    List<String> Function(String input, String output) jsPreambles =
        emptyPreamble,
    List<LineException> beforeExceptions = const <LineException>[],
    List<LineException> afterExceptions = const <LineException>[],
    bool useJsMethodNamesOnAbsence = false,
    String? Function(String? name) jsNameConverter = identityConverter,
    Directory? forcedTmpDir,
    int stackTraceLimit = 10,
    expandDart2jsInliningData = false}) async {
  Expect.isTrue(test.expectationMap.keys.contains(config),
      "No expectations found for '$config' in ${test.expectationMap.keys}");

  Directory tmpDir =
      forcedTmpDir ?? await Directory.systemTemp.createTemp('stacktrace-test');
  String input = '${tmpDir.path}/$inputFileName';
  File(input).writeAsStringSync(test.code);
  String output = '${tmpDir.path}/out.js';

  Expect.isTrue(await compile(input, output),
      'Unsuccessful compilation of test:\n${test.code}');
  File sourceMapFile = File('$output.map');
  Expect.isTrue(
      sourceMapFile.existsSync(), 'Source map not generated for $input');
  String sourceMapText = sourceMapFile.readAsStringSync();
  SingleMapping sourceMap = parseSingleMapping(jsonDecode(sourceMapText));
  String jsOutput = File(output).readAsStringSync();

  if (printJs) {
    print('JavaScript output:');
    print(jsOutput);
  }
  if (writeJs) {
    File('out.js').writeAsStringSync(jsOutput);
    File('out.js.map').writeAsStringSync(sourceMapText);
  }
  print('Running d8 $output');
  List<String> d8Arguments = <String>[];
  d8Arguments.add('--stack-trace-limit');
  d8Arguments.add('$stackTraceLimit');
  d8Arguments.addAll(jsPreambles(input, output));
  d8Arguments.add(output);
  ProcessResult runResult = Process.runSync(d8executable, d8Arguments);
  String out = '${runResult.stderr}\n${runResult.stdout}';
  if (verbose) {
    print('d8 output:');
    print(out);
  }
  List<String> lines = out.split(RegExp(r'(\r|\n|\r\n)'));
  List<StackTraceLine> jsStackTrace = <StackTraceLine>[];
  for (String line in lines) {
    if (line.startsWith('    at ')) {
      StackTraceLine stackTraceLine = StackTraceLine.fromText(line);
      if (stackTraceLine.lineNo != null && stackTraceLine.columnNo != null) {
        jsStackTrace.add(stackTraceLine);
      }
    }
  }

  List<StackTraceLine> dartStackTrace = <StackTraceLine>[];
  for (StackTraceLine line in jsStackTrace) {
    TargetEntry? targetEntry = _findColumn(
        line.lineNo! - 1, line.columnNo! - 1, _findLine(sourceMap, line));
    if (targetEntry == null || targetEntry.sourceUrlId == null) {
      dartStackTrace.add(line);
    } else {
      String fileName = sourceMap.urls[targetEntry.sourceUrlId!];
      int targetLine = targetEntry.sourceLine! + 1;
      int targetColumn = targetEntry.sourceColumn! + 1;

      if (expandDart2jsInliningData) {
        SourceFile file = SourceFile.fromString(jsOutput);
        int offset = file.getOffset(line.lineNo! - 1, line.columnNo! - 1);
        Map<int, List<FrameEntry>> frames =
            _loadInlinedFrameData(sourceMap, sourceMapText);
        List<int> indices = frames.keys.toList()..sort();
        int key = binarySearch<int>(indices, (i) => i > offset) - 1;
        int depth = 0;
        outer:
        while (key >= 0) {
          for (var frame in frames[indices[key]]!.reversed) {
            if (frame.isEmpty) break outer;
            if (frame.isPush) {
              if (depth <= 0) {
                dartStackTrace.add(StackTraceLine(
                    '${frame.inlinedMethodName}(inlined)',
                    fileName,
                    targetLine,
                    targetColumn,
                    isMapped: true));
                fileName = frame.callUri!;
                targetLine = frame.callLine! + 1;
                targetColumn = frame.callColumn! + 1;
              } else {
                depth--;
              }
            }
            if (frame.isPop) {
              depth++;
            }
          }
          key--;
        }
        targetEntry = findEnclosingFunction(jsOutput, file, offset, sourceMap);
      }

      String? methodName;
      if (targetEntry!.sourceNameId != null) {
        methodName = sourceMap.names[targetEntry.sourceNameId!];
      } else if (useJsMethodNamesOnAbsence) {
        methodName = jsNameConverter(line.methodName);
      }

      dartStackTrace.add(StackTraceLine(
          methodName, fileName, targetLine, targetColumn,
          isMapped: true));
    }
  }

  Expectations expectations = test.expectationMap[config]!;

  int expectedIndex = 0;
  List<StackTraceLine> unexpectedLines = <StackTraceLine>[];
  List<StackTraceLine> unexpectedBeforeLines = <StackTraceLine>[];
  List<StackTraceLine> unexpectedAfterLines = <StackTraceLine>[];
  for (StackTraceLine line in dartStackTrace) {
    bool found = false;
    if (expectedIndex < expectations.expectedLines.length) {
      StackTraceLine expectedLine = expectations.expectedLines[expectedIndex];
      if (line.methodName == expectedLine.methodName &&
          line.lineNo == expectedLine.lineNo &&
          line.columnNo == expectedLine.columnNo) {
        found = true;
        expectedIndex++;
      }
    }
    for (StackTraceLine unexpectedLine in expectations.unexpectedLines) {
      if (line.methodName == unexpectedLine.methodName &&
          line.lineNo == unexpectedLine.lineNo &&
          line.columnNo == unexpectedLine.columnNo) {
        unexpectedLines.add(line);
      }
    }
    if (line.isMapped && !found) {
      List<LineException> exceptions =
          expectedIndex == 0 ? beforeExceptions : afterExceptions;
      for (LineException exception in exceptions) {
        String fileName = exception.fileName;
        if (line.methodName == exception.methodName &&
            line.fileName!.endsWith(fileName)) {
          found = true;
        }
      }
      if (!found) {
        if (expectedIndex == 0) {
          unexpectedBeforeLines.add(line);
        } else {
          unexpectedAfterLines.add(line);
        }
      }
    }
  }
  if (verbose) {
    print('JavaScript stacktrace:');
    print(jsStackTrace.join('\n'));
    print('\nDart stacktrace:');
    print(dartStackTrace.join('\n'));
  }
  Expect.equals(
      expectedIndex,
      expectations.expectedLines.length,
      'Missing stack trace lines for test:\n${test.code}\n'
      'Actual:\n${dartStackTrace.join('\n')}\n\n'
      'Expected:\n${expectations.expectedLines.join('\n')}\n');
  Expect.isTrue(
      unexpectedLines.isEmpty,
      'Unexpected stack trace lines for test:\n${test.code}\n'
      'Actual:\n${dartStackTrace.join('\n')}\n\n'
      'Unexpected:\n${expectations.unexpectedLines.join('\n')}\n');
  Expect.isTrue(
      unexpectedBeforeLines.isEmpty && unexpectedAfterLines.isEmpty,
      'Unexpected stack trace lines:\n${test.code}\n'
      'Actual:\n${dartStackTrace.join('\n')}\n\n'
      'Unexpected before:\n${unexpectedBeforeLines.join('\n')}\n\n'
      'Unexpected after:\n${unexpectedAfterLines.join('\n')}\n');

  if (forcedTmpDir == null) {
    print("Deleting '${tmpDir.path}'.");
    tmpDir.deleteSync(recursive: true);
  }
}

class StackTraceLine {
  String? methodName;
  String? fileName;
  int? lineNo;
  int? columnNo;
  bool isMapped;

  StackTraceLine(this.methodName, this.fileName, this.lineNo, this.columnNo,
      {this.isMapped = false});

  /// Creates a [StackTraceLine] by parsing a d8 stack trace line [text]. The
  /// expected formats are
  ///
  ///     at <methodName>(<fileName>:<lineNo>:<columnNo>)
  ///     at <methodName>(<fileName>:<lineNo>)
  ///     at <methodName>(<fileName>)
  ///     at <fileName>:<lineNo>:<columnNo>
  ///     at <fileName>:<lineNo>
  ///     at <fileName>
  ///
  factory StackTraceLine.fromText(String text) {
    text = text.trim();
    assert(text.startsWith('at '));
    text = text.substring('at '.length);
    String? methodName;
    if (text.endsWith(')')) {
      int nameEnd = text.indexOf(' (');
      methodName = text.substring(0, nameEnd);
      text = text.substring(nameEnd + 2, text.length - 1);
    }
    int? lineNo;
    int? columnNo;
    String fileName;
    int lastColon = text.lastIndexOf(':');
    if (lastColon != -1) {
      int? lastValue = int.tryParse(text.substring(lastColon + 1));
      if (lastValue != null) {
        int secondToLastColon = text.lastIndexOf(':', lastColon - 1);
        if (secondToLastColon != -1) {
          int? secondToLastValue =
              int.tryParse(text.substring(secondToLastColon + 1, lastColon));
          if (secondToLastValue != null) {
            lineNo = secondToLastValue;
            columnNo = lastValue;
            fileName = text.substring(0, secondToLastColon);
          } else {
            lineNo = lastValue;
            fileName = text.substring(0, lastColon);
          }
        } else {
          lineNo = lastValue;
          fileName = text.substring(0, lastColon);
        }
      } else {
        fileName = text;
      }
    } else {
      fileName = text;
    }
    return StackTraceLine(methodName, fileName, lineNo, columnNo);
  }

  @override
  String toString() {
    StringBuffer sb = StringBuffer();
    sb.write('  at ');
    if (methodName != null) {
      sb.write(methodName);
      sb.write(' (');
      sb.write(fileName ?? '?');
      sb.write(':');
      sb.write(lineNo);
      sb.write(':');
      sb.write(columnNo);
      sb.write(')');
    } else {
      sb.write(fileName ?? '?');
      sb.write(':');
      sb.write(lineNo);
      sb.write(':');
      sb.write(columnNo);
    }
    return sb.toString();
  }
}

/// Returns [TargetLineEntry] which includes the location in the target [line]
/// number. In particular, the resulting entry is the last entry whose line
/// number is lower or equal to [line].
///
/// Copied from [SingleMapping._findLine].
TargetLineEntry? _findLine(SingleMapping sourceMap, StackTraceLine stLine) {
  String filename = stLine.fileName!
      .substring(stLine.fileName!.lastIndexOf(RegExp('[\\/]')) + 1);
  if (sourceMap.targetUrl != filename) return null;
  return _findLineInternal(sourceMap, stLine.lineNo! - 1);
}

TargetLineEntry? _findLineInternal(SingleMapping sourceMap, int line) {
  int index =
      binarySearch<TargetLineEntry>(sourceMap.lines, (e) => e.line > line);
  return (index <= 0) ? null : sourceMap.lines[index - 1];
}

/// Returns [TargetEntry] which includes the location denoted by
/// [line], [column]. If [lineEntry] corresponds to [line], then this will be
/// the last entry whose column is lower or equal than [column]. If
/// [lineEntry] corresponds to a line prior to [line], then the result will be
/// the very last entry on that line.
///
/// Copied from [SingleMapping._findColumn].
TargetEntry? _findColumn(int line, int column, TargetLineEntry? lineEntry) {
  if (lineEntry == null || lineEntry.entries.isEmpty) return null;
  if (lineEntry.line != line) return lineEntry.entries.last;
  var entries = lineEntry.entries;
  int index = binarySearch<TargetEntry>(entries, (e) => e.column > column);
  return (index <= 0) ? null : entries[index - 1];
}

/// Returns the path of the d8 executable.
String get d8executable {
  if (Platform.isWindows) {
    return 'third_party/d8/windows/d8.exe';
  } else if (Platform.isLinux) {
    return 'third_party/d8/linux/d8';
  } else if (Platform.isMacOS) {
    return 'third_party/d8/macos/d8';
  }
  throw UnsupportedError('Unsupported platform.');
}

/// A line allowed in the mapped stack trace.
class LineException {
  final String methodName;
  final String fileName;

  const LineException(this.methodName, this.fileName);
}

/// Search backwards in [sources] for a function declaration that includes the
/// [start] offset.
TargetEntry? findEnclosingFunction(
    String sources, SourceFile file, int start, SingleMapping mapping) {
  var index = start;
  while (true) {
    index = nextDeclarationCandidate(sources, index);
    if (index < 0) return null;
    var line = file.getLine(index);
    var lineEntry = _findLineInternal(mapping, line);
    var result = _findColumn(line, file.getColumn(index), lineEntry);
    if (result?.column == file.getColumn(index)) return result;
    index--;
  }
}

/// Returns the index of a candidate location of a enclosing function
/// declaration. We try to find the beginning of a `function` keyword or the
/// `(` of an ES6 method definition, but the search contains some false
/// positives. To rule out false positives, [findEnclosingFunction]
/// validates that the returned location contains a source-map entry, searching
/// for another candidate if not.
int nextDeclarationCandidate(String sources, int start) {
  var indexForFunctionKeyword = sources.lastIndexOf('function', start);
  // We attempt to identify potential method definitions by looking for any '('
  // that precedes a '{'. This method will fail if 1) Dart2JS starts emitting
  // functions with initializers or 2) sourcemap boundaries appear at '(' for
  // non-method-definition constructs.
  var indexForMethodDefinition = sources.lastIndexOf('{', start);
  if (indexForFunctionKeyword > indexForMethodDefinition ||
      indexForFunctionKeyword < 0) {
    return indexForFunctionKeyword;
  }
  indexForMethodDefinition = sources.lastIndexOf('(', indexForMethodDefinition);
  return indexForFunctionKeyword > indexForMethodDefinition
      ? indexForFunctionKeyword
      : indexForMethodDefinition;
}

Map<int, List<FrameEntry>> _loadInlinedFrameData(
    SingleMapping mapping, String sourceMapText) {
  var json = jsonDecode(sourceMapText);
  return Dart2jsMapping(mapping, json).frames;
}
