// 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:ffi' show Abi;
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;
      String? methodName;
      if (colonIndex >= 0) {
        indexText = text.substring(0, colonIndex);
        methodName = text.substring(colonIndex + 1);
      } else {
        indexText = text;
      }
      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 {
  final arch = Abi.current().toString().split('_')[1];
  if (Platform.isWindows) {
    return 'third_party/d8/windows/$arch/d8.exe';
  } else if (Platform.isLinux) {
    return 'third_party/d8/linux/$arch/d8';
  } else if (Platform.isMacOS) {
    return 'third_party/d8/macos/$arch/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;
}
