// Copyright (c) 2015, 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 'package:coverage/coverage.dart';
import 'package:coverage/src/util.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';

import 'test_util.dart';

final _isolateLibPath = p.join('test', 'test_files', 'test_app_isolate.dart');

final _sampleAppFileUri = p.toUri(p.absolute(testAppPath)).toString();
final _isolateLibFileUri = p.toUri(p.absolute(_isolateLibPath)).toString();

void main() {
  test('collect_coverage_api', () async {
    final coverage = coverageDataFromJson(await _collectCoverage());
    expect(coverage, isNotEmpty);

    final sources = coverage.sources();

    for (var sampleCoverageData in sources[_sampleAppFileUri]!) {
      expect(sampleCoverageData['hits'], isNotEmpty);
    }

    for (var sampleCoverageData in sources[_isolateLibFileUri]!) {
      expect(sampleCoverageData['hits'], isNotEmpty);
    }
  });

  test('collect_coverage_api with scoped output', () async {
    final coverage = coverageDataFromJson(
      await _collectCoverage(scopedOutput: <String>{}..add('coverage')),
    );
    expect(coverage, isNotEmpty);

    final sources = coverage.sources();

    for (var key in sources.keys) {
      final uri = Uri.parse(key);
      expect(uri.path.startsWith('coverage'), isTrue);
    }
  });

  test('collect_coverage_api with isolateIds', () async {
    final coverage =
        coverageDataFromJson(await _collectCoverage(isolateIds: true));
    expect(coverage, isEmpty);
  });

  test('collect_coverage_api with function coverage', () async {
    final coverage =
        coverageDataFromJson(await _collectCoverage(functionCoverage: true));
    expect(coverage, isNotEmpty);

    final sources = coverage.sources();

    final functionInfo = functionInfoFromSources(sources);

    expect(
      functionInfo[_sampleAppFileUri]!,
      {
        'main': 1,
        'usedMethod': 1,
        'unusedMethod': 0,
      },
    );

    expect(
      functionInfo[_isolateLibFileUri]!,
      {
        'BarClass.BarClass': 1,
        'fooAsync': 1,
        'fooSync': 1,
        'isolateTask': 1,
        'BarClass.baz': 1
      },
    );
  });

  test('collect_coverage_api with branch coverage', () async {
    final coverage =
        coverageDataFromJson(await _collectCoverage(branchCoverage: true));
    expect(coverage, isNotEmpty);

    final sources = coverage.sources();

    // Dart VM versions before 2.17 don't support branch coverage.
    expect(sources[_sampleAppFileUri],
        everyElement(containsPair('branchHits', isNotEmpty)));
    expect(sources[_isolateLibFileUri],
        everyElement(containsPair('branchHits', isNotEmpty)));
  }, skip: !platformVersionCheck(2, 17));

  test('collect_coverage_api with coverableLineCache', () async {
    final coverableLineCache = <String, Set<int>>{};
    final coverage =
        await _collectCoverage(coverableLineCache: coverableLineCache);
    final result = await HitMap.parseJson(
        coverage['coverage'] as List<Map<String, dynamic>>);

    expect(coverableLineCache, contains(_sampleAppFileUri));
    expect(coverableLineCache, contains(_isolateLibFileUri));

    // Expect that we have some missed lines.
    expect(result[_sampleAppFileUri]!.lineHits.containsValue(0), isTrue);
    expect(result[_isolateLibFileUri]!.lineHits.containsValue(0), isTrue);

    // Clear _sampleAppFileUri's cache entry, then gather coverage again. We're
    // doing this to verify that force compilation is disabled for these
    // libraries. The result should be that _isolateLibFileUri should be the
    // same, but _sampleAppFileUri should be missing all its missed lines.
    coverableLineCache[_sampleAppFileUri] = {};
    final coverage2 =
        await _collectCoverage(coverableLineCache: coverableLineCache);
    final result2 = await HitMap.parseJson(
        coverage2['coverage'] as List<Map<String, dynamic>>);

    // _isolateLibFileUri still has missed lines, but _sampleAppFileUri doesn't.
    expect(result2[_sampleAppFileUri]!.lineHits.containsValue(0), isFalse);
    expect(result2[_isolateLibFileUri]!.lineHits.containsValue(0), isTrue);

    // _isolateLibFileUri is the same. _sampleAppFileUri is the same, but
    // without all its missed lines.
    expect(result2[_isolateLibFileUri]!.lineHits,
        result[_isolateLibFileUri]!.lineHits);
    result[_sampleAppFileUri]!.lineHits.removeWhere((line, hits) => hits == 0);
    expect(result2[_sampleAppFileUri]!.lineHits,
        result[_sampleAppFileUri]!.lineHits);
  }, skip: !platformVersionCheck(3, 2));
}

Future<Map<String, dynamic>> _collectCoverage(
    {Set<String> scopedOutput = const {},
    bool isolateIds = false,
    bool functionCoverage = false,
    bool branchCoverage = false,
    Map<String, Set<int>>? coverableLineCache}) async {
  final openPort = await getOpenPort();

  // run the sample app, with the right flags
  final sampleProcess = await runTestApp(openPort);

  final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
  final isolateIdSet = isolateIds ? <String>{} : null;

  return collect(serviceUri, true, true, false, scopedOutput,
      timeout: timeout,
      isolateIds: isolateIdSet,
      functionCoverage: functionCoverage,
      branchCoverage: branchCoverage,
      coverableLineCache: coverableLineCache);
}
