// Copyright (c) 2013, 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';
import 'dart:io';

import "package:status_file/expectation.dart";

import 'command.dart';
import 'command_output.dart';
import 'configuration.dart';
import 'path.dart';
import 'summary_report.dart';
import 'terminal.dart';
import 'test_case.dart';
import 'utils.dart';

/// Controls how message strings are processed before being displayed.
class Formatter {
  /// Messages are left as-is.
  static const normal = Formatter._();

  /// Messages are wrapped in ANSI escape codes to color them for display on a
  /// terminal.
  static const color = _ColorFormatter();

  const Formatter._();

  /// Formats a success message.
  String passed(String message) => message;

  /// Formats a failure message.
  String failed(String message) => message;

  /// Formats a section header.
  String section(String message) => message;
}

class _ColorFormatter extends Formatter {
  static const _gray = "1;30";
  static const _green = "32";
  static const _red = "31";
  static const _escape = '\u001b';

  const _ColorFormatter() : super._();

  @override
  String passed(String message) => _color(message, _green);
  @override
  String failed(String message) => _color(message, _red);
  @override
  String section(String message) => _color(message, _gray);

  static String _color(String message, String color) =>
      "$_escape[${color}m$message$_escape[0m";
}

class EventListener {
  void testAdded() {}
  void done(TestCase test) {}
  void allTestsKnown() {}
  void allDone() {}
}

class ExitCodeSetter extends EventListener {
  @override
  void done(TestCase test) {
    if (test.unexpectedOutput) {
      exitCode = 1;
    }
  }
}

class TimedProgressPrinter extends EventListener {
  static const interval = Duration(minutes: 5);
  int _numTests = 0;
  int _numCompleted = 0;
  bool _allKnown = false;
  late Timer _timer;

  TimedProgressPrinter() {
    _timer = Timer.periodic(interval, callback);
  }

  void callback(Timer timer) {
    if (_allKnown) {
      Terminal.print('$_numCompleted out of $_numTests completed');
    }
    Terminal.print(
        "Tests running for ${(interval * timer.tick).inMinutes} minutes");
  }

  @override
  void testAdded() => _numTests++;

  @override
  void done(TestCase test) => _numCompleted++;

  @override
  void allTestsKnown() => _allKnown = true;

  @override
  void allDone() => _timer.cancel();
}

class IgnoredTestMonitor extends EventListener {
  static final int maxIgnored = 10;

  int countIgnored = 0;

  @override
  void done(TestCase test) {
    if (test.lastCommandOutput.result(test) == Expectation.ignore) {
      countIgnored++;
      if (countIgnored > maxIgnored) {
        Terminal.print(
            "\nMore than $maxIgnored tests were ignored due to flakes in");
        Terminal.print("the test infrastructure. Notify dart-engprod@.");
        Terminal.print("Output of the last ignored test was:");
        Terminal.print(_buildFailureOutput(test));
        exit(1);
      }
    }
  }

  @override
  void allDone() {
    if (countIgnored > 0) {
      Terminal.print("Ignored $countIgnored tests due to flaky infrastructure");
    }
  }
}

class UnexpectedCrashLogger extends EventListener {
  final archivedBinaries = <String, String>{};

  List<String> ldd(String path) {
    if (!Platform.isLinux) return <String>[];
    final out = Process.runSync("ldd", [path]).stdout as String;
    return out
        .split(' ')
        .where((String token) => token.startsWith('/'))
        .toList();
  }

  @override
  void done(TestCase test) {
    if (test.unexpectedOutput &&
        test.result == Expectation.crash &&
        test.lastCommandExecuted is ProcessCommand &&
        test.lastCommandOutput.hasCoreDump) {
      final mode = test.configuration.mode.name;
      final arch = test.configuration.architecture.name;

      var pid = "${test.lastCommandOutput.pid}";
      var lastCommand = test.lastCommandExecuted as ProcessCommand;
      final binaries = <String>[];

      // We might have a coredump for the process. This coredump will be
      // archived by CoreDumpArchiver (see tools/utils.py).
      //
      // For debugging purposes we need to archive the crashed binary as well.
      //
      // To simplify the archiving code we simply copy binaries into current
      // folder next to core dumps and name them
      // `binary.${mode}_${arch}_${binary_name}`.
      final binName = lastCommand.executable;
      final binFile = File(binName);
      final binBaseName = Path(binName).filename;
      if (binFile.existsSync()) {
        final archived = "binary.${mode}_${arch}_$binBaseName";
        binaries.add(archived);
        if (!archivedBinaries.containsKey(binName)) {
          TestUtils.copyFile(Path(binName), Path(archived));
          archivedBinaries[binName] = archived;
          // On Windows also copy PDB file for the binary.
          if (Platform.isWindows) {
            final pdbPath = Path("$binName.pdb");
            if (File(pdbPath.toNativePath()).existsSync()) {
              TestUtils.copyFile(pdbPath, Path("$archived.pdb"));
            }
          }
        }
      }
      // Copy libc, etc.
      for (final libName in ldd(binName)) {
        final libFile = File(libName);
        final libBaseName = Path(libName).filename;
        if (libFile.existsSync()) {
          final archived = "binary.${mode}_${arch}_$libBaseName";
          binaries.add(archived);
          if (!archivedBinaries.containsKey(libName)) {
            TestUtils.copyFile(Path(libName), Path(archived));
            archivedBinaries[libName] = archived;
          }
        }
      }

      final kernelServiceBaseName = 'kernel-service.dart.snapshot';
      final kernelService =
          File('${binFile.parent.path}/$kernelServiceBaseName');
      if (kernelService.existsSync()) {
        final archived = "binary.${mode}_${arch}_$kernelServiceBaseName";
        binaries.add(archived);
        if (!archivedBinaries.containsKey(kernelService.path)) {
          TestUtils.copyFile(Path(kernelService.path), Path(archived));
          archivedBinaries[kernelServiceBaseName] = archived;
        }
      }

      if (binaries.isNotEmpty) {
        // We have found and copied the binary.
        RandomAccessFile? unexpectedCrashesFile;
        try {
          unexpectedCrashesFile =
              File('unexpected-crashes').openSync(mode: FileMode.append);
          unexpectedCrashesFile.writeStringSync(
              "${test.displayName},$pid,${binaries.join(',')}\n");
        } catch (e) {
          Terminal.print('Failed to add crash to unexpected-crashes list: $e');
        } finally {
          try {
            if (unexpectedCrashesFile != null) {
              unexpectedCrashesFile.closeSync();
            }
          } catch (e) {
            Terminal.print('Failed to close unexpected-crashes file: $e');
          }
        }
      }
    }
  }
}

class SummaryPrinter extends EventListener {
  final bool jsonOnly;

  SummaryPrinter({this.jsonOnly = false});

  @override
  void allTestsKnown() {
    if (jsonOnly) {
      Terminal.print("JSON:");
      Terminal.print(jsonEncode(summaryReport.values));
    } else {
      summaryReport.printReport();
    }
  }
}

class TimingPrinter extends EventListener {
  final _commandToTestCases = <Command, List<TestCase>>{};
  final _commandOutputs = <CommandOutput>{};
  final DateTime _startTime;

  TimingPrinter(this._startTime);

  @override
  void done(TestCase test) {
    for (var commandOutput in test.commandOutputs.values) {
      var command = commandOutput.command;
      _commandOutputs.add(commandOutput);
      _commandToTestCases.putIfAbsent(command, () => <TestCase>[]).add(test);
    }
  }

  @override
  void allDone() {
    var d = DateTime.now().difference(_startTime);
    Terminal.print('\n--- Total time: ${_timeString(d)} ---');
    var outputs = _commandOutputs.toList();
    outputs.sort((a, b) {
      return b.time.inMilliseconds - a.time.inMilliseconds;
    });
    for (var commandOutput in outputs.take(20)) {
      var command = commandOutput.command;
      var testCases = _commandToTestCases[command]!;

      var testCasesDescription = testCases.map((testCase) {
        return "${testCase.configurationString}/${testCase.displayName}";
      }).join(', ');

      Terminal.print('${commandOutput.time} - '
          '${command.displayName} - '
          '$testCasesDescription');
    }
  }
}

class SkippedCompilationsPrinter extends EventListener {
  int _skippedCompilations = 0;

  @override
  void done(TestCase test) {
    for (var commandOutput in test.commandOutputs.values) {
      if (commandOutput.compilationSkipped) _skippedCompilations++;
    }
  }

  @override
  void allDone() {
    if (_skippedCompilations > 0) {
      Terminal.print(
          '\n$_skippedCompilations compilations were skipped because '
          'the previous output was already up to date.\n');
    }
  }
}

class TestFailurePrinter extends EventListener {
  final Formatter _formatter;

  TestFailurePrinter([this._formatter = Formatter.normal]);

  @override
  void done(TestCase test) {
    if (!test.unexpectedOutput) return;
    for (var line in _buildFailureOutput(test, _formatter)) {
      Terminal.print(line);
    }
  }
}

/// Prints a one-line summary of passed and failed tests.
class ResultCountPrinter extends EventListener {
  final Formatter _formatter;
  int _failedTests = 0;
  int _passedTests = 0;

  ResultCountPrinter(this._formatter);

  @override
  void done(TestCase test) {
    if (test.unexpectedOutput) {
      _failedTests++;
    } else {
      _passedTests++;
    }
  }

  @override
  void allDone() {
    var suffix = _passedTests != 1 ? 's' : '';
    var passed =
        '${_formatter.passed(_passedTests.toString())} test$suffix passed';

    String summary;
    if (_failedTests == 0) {
      summary = 'All $passed';
    } else {
      summary = '$passed, ${_formatter.failed(_failedTests.toString())} failed';
    }

    var marker = _formatter.section('===');
    Terminal.print('\n$marker $summary $marker');
  }
}

/// Prints a list of the tests that failed.
class FailedTestsPrinter extends EventListener {
  final List<TestCase> _failedTests = [];

  FailedTestsPrinter();

  @override
  void done(TestCase test) {
    if (test.unexpectedOutput) {
      _failedTests.add(test);
    }
  }

  @override
  void allDone() {
    if (_failedTests.isEmpty) return;

    Terminal.print('');
    Terminal.print('=== Failed tests ===');
    for (var test in _failedTests) {
      var result = test.realResult.toString();
      if (test.realExpected != Expectation.pass) {
        result += ' (expected ${test.realExpected})';
      }

      Terminal.print('${test.displayName}: $result');
    }
  }
}

class PassingStdoutPrinter extends EventListener {
  final Formatter _formatter;

  PassingStdoutPrinter([this._formatter = Formatter.normal]);

  @override
  void done(TestCase test) {
    if (!test.unexpectedOutput) {
      var lines = <String>[];
      var output = OutputWriter(_formatter, lines);
      for (final command in test.commands) {
        var commandOutput = test.commandOutputs[command];
        if (commandOutput == null) continue;

        commandOutput.describe(test, test.configuration.progress, output);
      }
      for (var line in lines) {
        Terminal.print(line);
      }
    }
  }

  @override
  void allDone() {}
}

abstract class ProgressIndicator extends EventListener {
  final DateTime _startTime;
  int _foundTests = 0;
  int _passedTests = 0;
  int _failedTests = 0;
  bool _allTestsKnown = false;

  ProgressIndicator(this._startTime);

  static EventListener? fromProgress(
      Progress progress, DateTime startTime, Formatter formatter) {
    switch (progress) {
      case Progress.compact:
        return CompactProgressIndicator(startTime, formatter);
      case Progress.line:
      case Progress.verbose:
        return LineProgressIndicator(startTime);
      case Progress.status:
        return null;
    }

    throw "unreachable";
  }

  @override
  void testAdded() {
    _foundTests++;
  }

  @override
  void done(TestCase test) {
    if (test.unexpectedOutput) {
      _failedTests++;
    } else {
      _passedTests++;
    }
    _printDoneProgress(test);
  }

  @override
  void allTestsKnown() {
    _allTestsKnown = true;
  }

  void _printDoneProgress(TestCase test);

  int get _completedTests => _passedTests + _failedTests;
}

abstract class CompactIndicator extends ProgressIndicator {
  CompactIndicator(super.startTime);
}

class CompactProgressIndicator extends CompactIndicator {
  final Formatter _formatter;

  CompactProgressIndicator(super.startTime, this._formatter);

  @override
  void _printDoneProgress(TestCase test) {
    var percent = ((_completedTests / _foundTests) * 100).toInt().toString();
    var progressPadded = (_allTestsKnown ? percent : '--').padLeft(3);
    var passedPadded = _passedTests.toString().padLeft(5);
    var failedPadded = _failedTests.toString().padLeft(5);
    var elapsed = DateTime.now().difference(_startTime);
    var progressLine = '\r[${_timeString(elapsed)} | $progressPadded% | '
        '+${_formatter.passed(passedPadded)} | '
        '-${_formatter.failed(failedPadded)}]';
    Terminal.writeLine(progressLine);
  }

  @override
  void allDone() {
    Terminal.finishLine();
  }
}

class LineProgressIndicator extends ProgressIndicator {
  LineProgressIndicator(super.startTime);

  @override
  void _printDoneProgress(TestCase test) {
    var status = 'pass';
    if (test.unexpectedOutput) {
      status = 'fail';
    }
    Terminal.print(
        'Done ${test.configurationString} ${test.displayName}: $status');
  }
}

String _timeString(Duration duration) {
  var min = duration.inMinutes;
  var sec = duration.inSeconds % 60;
  return '${min.toString().padLeft(2, '0')}:${sec.toString().padLeft(2, '0')}';
}

/// Builds and formats the failure output for a failed test.
class OutputWriter {
  final Formatter _formatter;
  final List<String?> _lines;
  String? _pendingSection;
  String? _pendingSubsection;
  bool _pendingLine = false;

  OutputWriter(this._formatter, this._lines);

  void section(String name) {
    _pendingSection = name;
    _pendingSubsection = null;
    _pendingLine = false;
  }

  void subsection(String name) {
    _pendingSubsection = name;
    _pendingLine = false;
  }

  void write(String? line) {
    _writePending();
    _lines.add(line);
  }

  void writeAll(Iterable<String> lines) {
    if (lines.isEmpty) return;
    _writePending();
    _lines.addAll(lines);
  }

  /// Writes a blank line that separates lines of output.
  ///
  /// If no output is written after this before the next section, subsection,
  /// or end out output, doesn't write the line.
  void separator() {
    _pendingLine = true;
  }

  /// Writes the current section header.
  void _writePending() {
    if (_pendingSection != null) {
      if (_lines.isNotEmpty) _lines.add("");
      _lines.add(_formatter.section("--- $_pendingSection:"));
      _pendingSection = null;
    }

    if (_pendingSubsection != null) {
      _lines.add("");
      _lines.add(_formatter.section("$_pendingSubsection:"));
      _pendingSubsection = null;
    }

    if (_pendingLine) {
      _lines.add("");
      _pendingLine = false;
    }
  }
}

List<String> _buildFailureOutput(TestCase test,
    [Formatter formatter = Formatter.normal]) {
  var lines = <String>[];
  var output = OutputWriter(formatter, lines);
  _writeFailureStatus(test, formatter, output);
  _writeFailureOutput(test, formatter, output);
  _writeFailureReproductionCommands(test, formatter, output);
  return lines;
}

List<String> _buildFailureLog(TestCase test) {
  final formatter = Formatter.normal;
  final lines = <String>[];
  final output = OutputWriter(formatter, lines);
  _writeFailureOutput(test, formatter, output);
  _writeFailureReproductionCommands(test, formatter, output);
  return lines;
}

void _writeFailureStatus(
    TestCase test, Formatter formatter, OutputWriter output) {
  output.write('');
  output.write(formatter
      .failed('FAILED: ${test.configurationString} ${test.displayName}'));

  output.write('Expected: ${test.expectedOutcomes.join(" ")}');
  output.write('Actual: ${test.result}');

  final ranAllCommands = test.commandOutputs.length == test.commands.length;
  if (!test.lastCommandOutput.hasTimedOut) {
    if (!ranAllCommands && !test.hasCompileError) {
      output.write('Unexpected compile error.');
    } else {
      if (test.hasCompileError) {
        output.write('Missing expected compile error.');
      }
      if (test.hasRuntimeError) {
        output.write('Missing expected runtime error.');
      }
    }
  }
}

void _writeFailureOutput(
    TestCase test, Formatter formatter, OutputWriter output) {
  for (var i = 0; i < test.commands.length; i++) {
    var command = test.commands[i];
    var commandOutput = test.commandOutputs[command];
    if (commandOutput == null) continue;

    var time = niceTime(commandOutput.time);
    output.section('Command "${command.displayName}" (took $time)');
    output.write(command.toString());
    commandOutput.describe(test, test.configuration.progress, output);
  }
}

void _writeFailureReproductionCommands(
    TestCase test, Formatter formatter, OutputWriter output) {
  final ranAllCommands = test.commandOutputs.length == test.commands.length;
  if (test.configuration.runtime.isBrowser && ranAllCommands) {
    // Additional command for rerunning the steps locally after the fact.
    output.section('To debug locally, run');
    output.write(test.configuration.servers.commandLine);
  }

  output.section('Re-run this test');
  List<String> arguments;
  if (Platform.isFuchsia) {
    arguments = [Platform.executable, Platform.script.path];
  } else {
    arguments = ['python3', 'tools/test.py'];
  }
  arguments.addAll(test.configuration.reproducingArguments);
  arguments.add(test.displayName);

  output.write(arguments.map(escapeCommandLineArgument).join(' '));
}

/// Writes a results.json file with a line for each test.
/// Each line is a json map with the test name and result and expected result.
class ResultWriter extends EventListener {
  final List<Map> _results = [];
  final List<Map> _logs = [];
  final String _outputDirectory;

  ResultWriter(this._outputDirectory) {
    Directory(_outputDirectory).createSync(recursive: true);
  }

  @override
  void allTestsKnown() {
    // Write an empty result log file, that will be overwritten if any tests
    // are actually run, when the allDone event handler is invoked.
    writeOutputFile([], TestUtils.resultsFileName);
    writeOutputFile([], TestUtils.logsFileName);
  }

  String newlineTerminated(Iterable<String> lines) =>
      lines.map((l) => '$l\n').join();

  @override
  void done(TestCase test) {
    var name = test.displayName;
    var index = name.indexOf('/');
    var suite = name.substring(0, index);
    var testName = name.substring(index + 1);
    var time = test.commandOutputs.values
        .fold<Duration>(Duration.zero, (d, o) => d + o.time);
    var experiments = test.experiments;
    var record = {
      "name": name,
      "configuration": test.configuration.configuration.name,
      "suite": suite,
      "test_name": testName,
      "time_ms": time.inMilliseconds,
      "result": test.realResult.toString(),
      "expected": test.realExpected.toString(),
      "matches": test.realResult.canBeOutcomeOf(test.realExpected),
      if (experiments.isNotEmpty) "experiments": experiments,
    };
    _results.add(record);
    if (test.configuration.writeLogs && record['matches'] != true) {
      var log = {
        'name': name,
        'configuration': record['configuration'],
        'result': record['result'],
        'log': newlineTerminated(_buildFailureLog(test))
      };
      _logs.add(log);
    }
  }

  @override
  void allDone() {
    writeOutputFile(_results, TestUtils.resultsFileName);
    writeOutputFile(_logs, TestUtils.logsFileName);
  }

  void writeOutputFile(List<Map> results, String fileName) {
    var path = Uri.directory(_outputDirectory).resolve(fileName);
    File.fromUri(path)
        .writeAsStringSync(newlineTerminated(results.map(jsonEncode)));
  }
}
