// Copyright (c) 2022, 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.

@Tags(['integration'])
library;

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

import 'package:coverage/coverage.dart';
import 'package:coverage/src/util.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_process/test_process.dart';

import 'test_util.dart';

final _collectAppPath = p.join('bin', 'collect_coverage.dart');
final _funcCovApp = p.join('test', 'test_files', 'function_coverage_app.dart');
final _sampleAppFileUri = p.toUri(p.absolute(_funcCovApp)).toString();

void main() {
  test('Function coverage', () async {
    final resultString = await _collectCoverage();
    final jsonResult = json.decode(resultString) as Map<String, dynamic>;
    final coverage = jsonResult['coverage'] as List;
    final hitMap = await HitMap.parseJson(
      coverage.cast<Map<String, dynamic>>(),
    );

    // function_coverage_app.dart.
    expect(hitMap, contains(_sampleAppFileUri));
    final isolateFile = hitMap[_sampleAppFileUri]!;
    expect(isolateFile.funcHits, {
      7: 1,
      16: 1,
      21: 1,
      25: 1,
      29: 1,
      36: 1,
      42: 1,
      47: 1,
    });
    expect(isolateFile.funcNames, {
      7: 'normalFunction',
      16: 'SomeClass.SomeClass',
      21: 'SomeClass.normalMethod',
      25: 'SomeClass.staticMethod',
      29: 'SomeClass.abstractMethod',
      36: 'SomeExtension.extensionMethod',
      42: 'OtherClass.otherMethod',
      47: 'main',
    });

    // test_library.dart.
    final testLibraryPath = p.absolute(
      p.join('test', 'test_files', 'test_library.dart'),
    );
    final testLibraryUri = p.toUri(testLibraryPath).toString();
    expect(hitMap, contains(testLibraryUri));
    final libraryfile = hitMap[testLibraryUri]!;
    expect(libraryfile.funcHits, {7: 1});
    expect(libraryfile.funcNames, {7: 'libraryFunction'});

    // test_library_part.dart.
    final testLibraryPartPath = p.absolute(
      p.join('test', 'test_files', 'test_library_part.dart'),
    );
    final testLibraryPartUri = p.toUri(testLibraryPartPath).toString();
    expect(hitMap, contains(testLibraryPartUri));
    final libraryPartFile = hitMap[testLibraryPartUri]!;
    expect(libraryPartFile.funcHits, {7: 1});
    expect(libraryPartFile.funcNames, {7: 'otherLibraryFunction'});
  });
}

Future<String> _collectCoverage() async {
  expect(FileSystemEntity.isFileSync(_funcCovApp), isTrue);

  // Run the sample app with the right flags.
  final sampleProcess = await TestProcess.start(Platform.resolvedExecutable, [
    '--enable-vm-service=0',
    '--pause_isolates_on_exit',
    _funcCovApp,
  ]);

  final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());

  // Run the collection tool.
  final toolResult = await TestProcess.start(Platform.resolvedExecutable, [
    _collectAppPath,
    '--function-coverage',
    '--uri',
    '$serviceUri',
    '--resume-isolates',
    '--wait-paused',
  ]);

  await toolResult
      .shouldExit(0)
      .timeout(
        timeout,
        onTimeout: () =>
            throw StateError('We timed out waiting for the tool to finish.'),
      );

  await sampleProcess.shouldExit();

  return toolResult.stdoutStream().join('\n');
}
