// Copyright (c) 2020, 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:convert';

import 'package:path/path.dart' as p;
import 'package:test_descriptor/test_descriptor.dart' as d;

import 'package:test/test.dart';
import 'package:test_core/src/runner/version.dart';

/// Asserts that the outputs from running tests with a JSON reporter match the
/// given expectations.
///
/// Verifies that [outputLines] matches each set of matchers in [expected],
/// includes the [testPid] from the test process, and ends with [done].
Future<void> expectJsonReport(
    List<String> outputLines,
    int testPid,
    List<List<Object /*Map|Matcher*/ >> expected,
    Map<Object, Object> done) async {
  // Ensure the output is of the same length, including start, done and all
  // suites messages.
  expect(outputLines.length,
      equals(expected.fold<int>(3, (int a, m) => a + m.length)),
      reason: 'Expected $outputLines to match $expected.');

  dynamic decodeLine(String l) => jsonDecode(l)
    ..remove('time')
    ..remove('stackTrace');

  // Should contain all suites message.
  expect(outputLines.map(decodeLine), containsAll([allSuitesJson()]));

  // A single start event is emitted first.
  final _start = {
    'type': 'start',
    'protocolVersion': '0.1.1',
    'runnerVersion': testVersion,
    'pid': testPid,
  };
  expect(decodeLine(outputLines.first), equals(_start));

  // A single done event is emmited last.
  expect(decodeLine(outputLines.last), equals(done));

  for (var value in expected) {
    expect(outputLines.map(decodeLine), containsAllInOrder(value));
  }
}

/// Returns the event emitted by the JSON reporter providing information about
/// all suites.
///
/// The [count] defaults to 1.
Map<String, Object> allSuitesJson({int count = 1}) {
  return {'type': 'allSuites', 'count': count};
}

/// Returns the event emitted by the JSON reporter indicating that a suite has
/// begun running.
///
/// The [platform] defaults to `"vm"`, the [path] defaults to `"test.dart"`.
Map<String, Object> suiteJson(int id,
    {String platform = 'vm', String path = 'test.dart'}) {
  return {
    'type': 'suite',
    'suite': {
      'id': id,
      'platform': platform,
      'path': path,
    }
  };
}

/// Returns the event emitted by the JSON reporter indicating that a group has
/// begun running.
///
/// If [skip] is `true`, the group is expected to be marked as skipped without a
/// reason. If it's a [String], the group is expected to be marked as skipped
/// with that reason.
///
/// The [testCount] parameter indicates the number of tests in the group. It
/// defaults to 1.
Map<String, Object> groupJson(int id,
    {String? name,
    int? suiteID,
    int? parentID,
    Object? skip,
    int? testCount,
    int? line,
    int? column}) {
  if ((line == null) != (column == null)) {
    throw ArgumentError(
        'line and column must either both be null or both be passed');
  }

  return {
    'type': 'group',
    'group': {
      'id': id,
      'name': name ?? '',
      'suiteID': suiteID ?? 0,
      'parentID': parentID,
      'metadata': metadataJson(skip: skip),
      'testCount': testCount ?? 1,
      'line': line,
      'column': column,
      'url': line == null
          ? null
          : p.toUri(p.join(d.sandbox, 'test.dart')).toString()
    }
  };
}

/// Returns the event emitted by the JSON reporter indicating that a test has
/// begun running.
///
/// If [parentIDs] is passed, it's the IDs of groups containing this test. If
/// [skip] is `true`, the test is expected to be marked as skipped without a
/// reason. If it's a [String], the test is expected to be marked as skipped
/// with that reason.
Map<String, Object> testStartJson(int id, String name,
    {int? suiteID,
    Iterable<int>? groupIDs,
    int? line,
    int? column,
    String? url,
    Object? skip,
    int? root_line,
    int? root_column,
    String? root_url}) {
  if ((line == null) != (column == null)) {
    throw ArgumentError(
        'line and column must either both be null or both be passed');
  }

  url ??=
      line == null ? null : p.toUri(p.join(d.sandbox, 'test.dart')).toString();
  var expected = {
    'type': 'testStart',
    'test': {
      'id': id,
      'name': name,
      'suiteID': suiteID ?? 0,
      'groupIDs': groupIDs ?? [2],
      'metadata': metadataJson(skip: skip),
      'line': line,
      'column': column,
      'url': url,
    }
  };
  var testObj = expected['test'] as Map<String, dynamic>;
  if (root_line != null) {
    testObj['root_line'] = root_line;
  }
  if (root_column != null) {
    testObj['root_column'] = root_column;
  }
  if (root_url != null) {
    testObj['root_url'] = root_url;
  }
  return expected;
}

/// Returns the event emitted by the JSON reporter indicating that a test
/// printed [message].
Matcher printJson(int id, dynamic /*String|Matcher*/ message,
    {String type = 'print'}) {
  return allOf(
    hasLength(4),
    containsPair('type', 'print'),
    containsPair('testID', id),
    containsPair('message', message),
    containsPair('messageType', type),
  );
}

/// Returns the event emitted by the JSON reporter indicating that a test
/// emitted [error].
///
/// The [isFailure] parameter indicates whether the error was a [TestFailure] or
/// not.
Map<String, Object> errorJson(int id, String error, {bool isFailure = false}) {
  return {
    'type': 'error',
    'testID': id,
    'error': error,
    'isFailure': isFailure
  };
}

/// Returns the event emitted by the JSON reporter indicating that a test
/// finished.
///
/// The [result] parameter indicates the result of the test. It defaults to
/// `"success"`.
///
/// The [hidden] parameter indicates whether the test should not be displayed
/// after finishing. The [skipped] parameter indicates whether the test was
/// skipped.
Map<String, Object> testDoneJson(int id,
    {String result = 'success', bool hidden = false, bool skipped = false}) {
  return {
    'type': 'testDone',
    'testID': id,
    'result': result,
    'hidden': hidden,
    'skipped': skipped
  };
}

/// Returns the event emitted by the JSON reporter indicating that the entire
/// run finished.
Map<String, Object> doneJson({bool success = true}) =>
    {'type': 'done', 'success': success};

/// Returns the serialized metadata corresponding to [skip].
Map<String, Object?> metadataJson({skip}) {
  if (skip == true) {
    return {'skip': true, 'skipReason': null};
  } else if (skip is String) {
    return {'skip': true, 'skipReason': skip};
  } else {
    return {'skip': false, 'skipReason': null};
  }
}
