// Copyright 2014 The Flutter Authors. 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 'dart:io';

import 'package:file/memory.dart';

import '../luci_resultdb.dart';
import '../tool_subsharding.dart';
import 'common.dart';

const String _kMetrics = '''
{"protocolVersion":"0.1.1","runnerVersion":"1.25.0","pid":1,"type":"start","time":0}
{"suite":{"id":0,"platform":"vm","path":"test/foo_test.dart"},"type":"suite","time":0}
{"test":{"id":1,"name":"loading test/foo_test.dart","suiteID":0,"groupIDs":[],"metadata":{"skip":false,"skipReason":null},"line":null,"column":null,"url":null},"type":"testStart","time":0}
{"testID":1,"result":"success","skipped":false,"hidden":true,"type":"testDone","time":1}
{"test":{"id":2,"name":"passing test","suiteID":0,"groupIDs":[],"metadata":{"skip":false,"skipReason":null},"line":10,"column":3,"url":"file:///foo"},"type":"testStart","time":2}
{"testID":2,"result":"success","skipped":false,"hidden":false,"type":"testDone","time":102}
{"test":{"id":3,"name":"failing test","suiteID":0,"groupIDs":[],"metadata":{"skip":false,"skipReason":null},"line":20,"column":3,"url":"file:///foo"},"type":"testStart","time":102}
{"testID":3,"result":"failure","skipped":false,"hidden":false,"type":"testDone","time":152}
{"test":{"id":4,"name":"skipped test","suiteID":0,"groupIDs":[],"metadata":{"skip":true,"skipReason":null},"line":30,"column":3,"url":"file:///foo"},"type":"testStart","time":152}
{"testID":4,"result":"success","skipped":true,"hidden":false,"type":"testDone","time":152}
{"success":false,"type":"done","time":200}''';

TestFileReporterResults _parse() {
  final fileSystem = MemoryFileSystem.test();
  final File file = fileSystem.file('metrics');
  file.writeAsStringSync(_kMetrics);
  return TestFileReporterResults.fromFile(file);
}

String _caseName(LuciTestResult result) => result.testId.caseName;

void main() {
  group('convertToLuciTestResultsFormat', () {
    test('converts each non-hidden test into a structured ResultDB TestResult', () {
      final List<LuciTestResult> results = convertToLuciTestResultsFormat(_parse());

      // The hidden "loading ..." bookkeeping test is excluded.
      expect(results, hasLength(3));

      final byCase = <String, LuciTestResult>{
        for (final LuciTestResult r in results) _caseName(r): r,
      };

      expect(byCase.keys, containsAll(<String>['passing test', 'failing test', 'skipped test']));
      // The module name is the test file, and the scheme is the level-free
      // 'flat' scheme, so file and test name are separate columns in the UI.
      for (final LuciTestResult(
            testId: LuciStructuredTestId(:moduleName, :moduleScheme, :moduleVariant),
          )
          in results) {
        expect(moduleName, 'test/foo_test.dart');
        expect(moduleScheme, 'flat');
        expect(moduleVariant, <String, String>{});
      }
    });

    test('strips rootDirectory prefix from absolute suite paths', () {
      const metrics =
          '{"protocolVersion":"0.1.1","runnerVersion":"1.25.0","pid":1,"type":"start","time":0}\n'
          '{"suite":{"id":0,"platform":"vm","path":"/b/s/w/ir/x/w/flutter/dev/foo/bar_test.dart"},"type":"suite","time":0}\n'
          '{"test":{"id":2,"name":"my test","suiteID":0,"groupIDs":[],"metadata":{"skip":false,"skipReason":null},"line":10,"column":3,"url":"file:///foo"},"type":"testStart","time":2}\n'
          '{"testID":2,"result":"success","skipped":false,"hidden":false,"type":"testDone","time":102}\n'
          '{"success":true,"type":"done","time":200}';
      final fileSystem = MemoryFileSystem.test();
      final File file = fileSystem.file('metrics')..writeAsStringSync(metrics);
      final parsed = TestFileReporterResults.fromFile(file);

      final List<LuciTestResult> stripped = convertToLuciTestResultsFormat(
        parsed,
        rootDirectory: '/b/s/w/ir/x/w/flutter',
      );
      final [LuciTestResult(testId: LuciStructuredTestId(:String moduleName, :String caseName))] =
          stripped;
      expect(moduleName, 'dev/foo/bar_test.dart');
      expect(caseName, 'my test');

      // Without a rootDirectory, the absolute path is preserved.
      final [
        LuciTestResult(testId: LuciStructuredTestId(moduleName: String unstrippedModuleName)),
      ] = convertToLuciTestResultsFormat(
        parsed,
      );
      expect(unstrippedModuleName, '/b/s/w/ir/x/w/flutter/dev/foo/bar_test.dart');
    });

    test('resolves relative suite paths against the working directory', () {
      const metrics =
          '{"protocolVersion":"0.1.1","runnerVersion":"1.25.0","pid":1,"type":"start","time":0}\n'
          '{"suite":{"id":0,"platform":"vm","path":"test/bar_test.dart"},"type":"suite","time":0}\n'
          '{"test":{"id":2,"name":"my test","suiteID":0,"groupIDs":[],"metadata":{"skip":false,"skipReason":null},"line":10,"column":3,"url":"file:///foo"},"type":"testStart","time":2}\n'
          '{"testID":2,"result":"success","skipped":false,"hidden":false,"type":"testDone","time":102}\n'
          '{"success":true,"type":"done","time":200}';
      final fileSystem = MemoryFileSystem.test();
      final File file = fileSystem.file('metrics')..writeAsStringSync(metrics);
      final parsed = TestFileReporterResults.fromFile(file);

      // A `packages/flutter` shard reports suite paths relative to its working
      // directory; resolving against it yields a repo-relative module name.
      final List<LuciTestResult> results = convertToLuciTestResultsFormat(
        parsed,
        workingDirectory: '/b/s/w/ir/x/w/flutter/packages/flutter',
        rootDirectory: '/b/s/w/ir/x/w/flutter',
      );
      final [LuciTestResult(testId: LuciStructuredTestId(:String moduleName))] = results;
      expect(moduleName, 'packages/flutter/test/bar_test.dart');
    });

    test('escapes colons and backslashes in the case name', () {
      const metrics =
          '{"protocolVersion":"0.1.1","runnerVersion":"1.25.0","pid":1,"type":"start","time":0}\n'
          '{"suite":{"id":0,"platform":"vm","path":"test/foo_test.dart"},"type":"suite","time":0}\n'
          '{"test":{"id":2,"name":"Group: sub\\\\path does x","suiteID":0,"groupIDs":[],"metadata":{"skip":false,"skipReason":null},"line":10,"column":3,"url":"file:///foo"},"type":"testStart","time":2}\n'
          '{"testID":2,"result":"success","skipped":false,"hidden":false,"type":"testDone","time":102}\n'
          '{"success":true,"type":"done","time":200}';
      final fileSystem = MemoryFileSystem.test();
      final File file = fileSystem.file('metrics')..writeAsStringSync(metrics);
      final parsed = TestFileReporterResults.fromFile(file);

      final List<LuciTestResult> results = convertToLuciTestResultsFormat(parsed);
      // The raw test name is `Group: sub\path does x`; ':' becomes '\:' and the
      // backslash becomes '\\'.
      final [LuciTestResult(testId: LuciStructuredTestId(:String caseName))] = results;
      expect(caseName, r'Group\: sub\\path does x');
    });

    test('maps status and expectedness correctly', () {
      final List<LuciTestResult> results = convertToLuciTestResultsFormat(_parse());
      final byId = <String, LuciTestResult>{
        for (final LuciTestResult r in results) _caseName(r): r,
      };

      final LuciTestResult pass = byId['passing test']!;
      expect((pass.status, pass.expected), ('PASS', true));

      final LuciTestResult fail = byId['failing test']!;
      expect((fail.status, fail.expected), ('FAIL', false));

      final LuciTestResult skip = byId['skipped test']!;
      expect((skip.status, skip.expected), ('SKIP', true));
    });

    test('marks failing tests as expected when expectFailure is true', () {
      final List<LuciTestResult> results = convertToLuciTestResultsFormat(
        _parse(),
        expectFailure: true,
      );
      final byId = <String, LuciTestResult>{
        for (final LuciTestResult r in results) _caseName(r): r,
      };

      // The failing test keeps its FAIL status but is now an *expected* failure,
      // so ResultDB won't surface it as a red regression (e.g. the
      // test_smoke_test negative tests run with expectFailure: true).
      final LuciTestResult fail = byId['failing test']!;
      expect((fail.status, fail.expected), ('FAIL', true));

      // Passing and skipped tests remain expected as well.
      expect(byId['passing test']!.expected, true);
      expect(byId['skipped test']!.expected, true);
    });

    test('emits a proto Duration string and unique result ids', () {
      final List<LuciTestResult> results = convertToLuciTestResultsFormat(_parse());

      for (final r in results) {
        expect(r.duration, matches(r'^\d+\.\d+s$'));
      }
      final resultIds = <String>{for (final LuciTestResult r in results) r.resultId};
      expect(resultIds, hasLength(results.length));

      // The passing test ran from t=2ms to t=102ms => 0.1s.
      final LuciTestResult pass = results.firstWhere(
        (LuciTestResult r) => _caseName(r) == 'passing test',
      );
      expect(pass.duration, '0.100000s');
    });
  });

  group('ResultDbRecorder.fromEnvironment', () {
    test('returns null when resultdb is absent from LUCI_CONTEXT', () {
      final Directory dir = Directory.systemTemp.createTempSync('luci_resultdb_test');
      addTearDown(() => tryToDelete(dir));
      final context = File('${dir.path}/luci_context.json')
        ..writeAsStringSync(json.encode(<String, Object?>{'luciexe': <String, Object?>{}}));
      expect(
        ResultDbRecorder.fromEnvironment(<String, String>{'LUCI_CONTEXT': context.path}),
        isNull,
      );
    });

    test('returns null (does not throw) when LUCI_CONTEXT is malformed JSON', () {
      final Directory dir = Directory.systemTemp.createTempSync('luci_resultdb_test');
      addTearDown(() => tryToDelete(dir));
      final context = File('${dir.path}/luci_context.json')..writeAsStringSync('{not valid json');
      expect(
        ResultDbRecorder.fromEnvironment(<String, String>{'LUCI_CONTEXT': context.path}),
        isNull,
      );
    });

    test('parses hostname and current_invocation from LUCI_CONTEXT', () {
      final Directory dir = Directory.systemTemp.createTempSync('luci_resultdb_test');
      addTearDown(() => tryToDelete(dir));
      final context = File('${dir.path}/luci_context.json')
        ..writeAsStringSync(
          json.encode(<String, Object?>{
            'resultdb': <String, Object?>{
              'hostname': 'results.api.luci.app',
              'current_invocation': <String, Object?>{
                'name': 'invocations/build-123',
                'update_token': 'tok',
              },
            },
          }),
        );
      final ResultDbRecorder? recorder = ResultDbRecorder.fromEnvironment(<String, String>{
        'LUCI_CONTEXT': context.path,
      });
      if (recorder case final rec?) {
        expect(
          (rec.host, rec.invocation, rec.updateToken),
          ('results.api.luci.app', 'invocations/build-123', 'tok'),
        );
        rec.close();
      } else {
        fail('Expected non-null recorder');
      }
    });
  });

  group('ResultDbRecorder.reportTestResults', () {
    test('serializes each result under requests[].testResult', () async {
      final HttpServer server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
      addTearDown(() => server.close(force: true));

      final bodies = <Map<String, Object?>>[];
      final tokens = <String>[];
      final paths = <String>[];
      server.listen((HttpRequest request) async {
        paths.add(request.uri.path);
        tokens.add(request.headers.value('update-token') ?? '');
        final String body = await utf8.decoder.bind(request).join();
        bodies.add(json.decode(body) as Map<String, Object?>);
        request.response.statusCode = HttpStatus.ok;
        request.response.write('{}');
        await request.response.close();
      });

      // Use a client whose https requests are redirected to our http server by
      // connecting directly; HttpClient does not allow that, so we instead
      // exercise the batching/serialization logic against the local server by
      // constructing the recorder with an http HttpClient is not needed: the
      // body format is what we assert here through the public API.
      final recorder = _HttpRecorder(
        host: '${server.address.host}:${server.port}',
        invocation: 'invocations/build-123',
        updateToken: 'my-token',
      );
      addTearDown(recorder.close);

      await recorder.reportTestResults(<LuciTestResult>[
        const LuciTestResult(
          testId: LuciStructuredTestId(moduleName: 'm', caseName: 'a'),
          resultId: '0',
          status: 'PASS',
          expected: true,
          duration: '0.000000s',
        ),
        const LuciTestResult(
          testId: LuciStructuredTestId(moduleName: 'm', caseName: 'b'),
          resultId: '1',
          status: 'FAIL',
          expected: false,
          duration: '0.000000s',
        ),
      ]);

      expect(bodies, hasLength(1));
      expect(paths.single, '/prpc/luci.resultdb.v1.Recorder/BatchCreateTestResults');
      expect(tokens.single, 'my-token');
      if (bodies.single case {
        'invocation': 'invocations/build-123',
        'requests': [{'testResult': {'testIdStructured': {'caseName': 'a'}}}, _],
      }) {
        // Matched expected structure.
      } else {
        fail('Unexpected body: ${bodies.single}');
      }
    });
  });
}

/// A [ResultDbRecorder] that talks plain HTTP, for testing against a local
/// [HttpServer] (the production recorder always uses https).
class _HttpRecorder extends ResultDbRecorder {
  _HttpRecorder({required super.host, required super.invocation, required super.updateToken});

  @override
  Future<void> reportTestResults(List<LuciTestResult> testResults) async {
    final client = HttpClient();
    try {
      final Uri url = Uri.parse(
        'http://$host/prpc/luci.resultdb.v1.Recorder/BatchCreateTestResults',
      );
      final HttpClientRequest request = await client.postUrl(url);
      request.headers.set(HttpHeaders.contentTypeHeader, 'application/json');
      request.headers.set('update-token', updateToken);
      request.add(
        utf8.encode(
          json.encode(<String, Object?>{
            'invocation': invocation,
            'requests': <Map<String, Object?>>[
              for (final LuciTestResult result in testResults)
                <String, Object?>{'testResult': result.toJson()},
            ],
          }),
        ),
      );
      final HttpClientResponse response = await request.close();
      await response.drain<void>();
    } finally {
      client.close(force: true);
    }
  }
}
