// 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 'package:args/args.dart';
import 'package:conductor_core/src/globals.dart';
import 'package:conductor_core/src/proto/conductor_state.pb.dart' as pb;

import './common.dart';

void main() {
  test('assertsEnabled returns true in test suite', () {
    expect(assertsEnabled(), true);
  });

  group('getNewPrLink', () {
    const String userName = 'flutterer';
    const String releaseChannel = 'beta';
    const String releaseVersion = '1.2.0-3.4.pre';
    const String candidateBranch = 'flutter-1.2-candidate.3';
    const String workingBranch = 'cherrypicks-$candidateBranch';
    const String dartRevision = 'fe9708ab688dcda9923f584ba370a66fcbc3811f';
    const String engineCherrypick1 = 'a5a25cd702b062c24b2c67b8d30b5cb33e0ef6f0';
    const String engineCherrypick2 = '94d06a2e1d01a3b0c693b94d70c5e1df9d78d249';
    const String frameworkCherrypick =
        'a5a25cd702b062c24b2c67b8d30b5cb33e0ef6f0';

    final RegExp titlePattern = RegExp(r'&title=(.*)&');
    final RegExp bodyPattern = RegExp(r'&body=(.*)$');

    late pb.ConductorState state;

    setUp(() {
      state = pb.ConductorState(
        engine: pb.Repository(
          candidateBranch: candidateBranch,
          cherrypicks: <pb.Cherrypick>[
            pb.Cherrypick(trunkRevision: engineCherrypick1),
            pb.Cherrypick(trunkRevision: engineCherrypick2),
          ],
          dartRevision: dartRevision,
          workingBranch: workingBranch,
        ),
        framework: pb.Repository(
          candidateBranch: candidateBranch,
          cherrypicks: <pb.Cherrypick>[
            pb.Cherrypick(trunkRevision: frameworkCherrypick),
          ],
          workingBranch: workingBranch,
        ),
        releaseChannel: releaseChannel,
        releaseVersion: releaseVersion,
      );
    });

    test('throws on an invalid repoName', () {
      expect(
        () => getNewPrLink(
          repoName: 'flooter',
          userName: userName,
          state: state,
        ),
        throwsExceptionWith(
          'Expected repoName to be one of flutter or engine but got flooter.',
        ),
      );
    });

    test('returns a valid URL for engine', () {
      final String link = getNewPrLink(
        repoName: 'engine',
        userName: userName,
        state: state,
      );
      expect(
        link,
        contains('https://github.com/flutter/engine/compare/'),
      );
      expect(
        link,
        contains('$candidateBranch...$userName:$workingBranch?expand=1'),
      );
      expect(
          Uri.decodeQueryComponent(
              titlePattern.firstMatch(link)?.group(1) ?? ''),
          '[flutter_releases] Flutter $releaseChannel $releaseVersion Engine Cherrypicks');
      final String expectedBody = '''
# Flutter $releaseChannel $releaseVersion Engine

## Scheduled Cherrypicks

- Roll dart revision: dart-lang/sdk@${dartRevision.substring(0, 9)}
- commit: flutter/engine@${engineCherrypick1.substring(0, 9)}
- commit: flutter/engine@${engineCherrypick2.substring(0, 9)}
''';
      expect(
        Uri.decodeQueryComponent(bodyPattern.firstMatch(link)?.group(1) ?? ''),
        expectedBody,
      );
    });

    test('returns a valid URL for framework', () {
      final String link = getNewPrLink(
        repoName: 'flutter',
        userName: userName,
        state: state,
      );
      expect(
        link,
        contains('https://github.com/flutter/flutter/compare/'),
      );
      expect(
        link,
        contains('$candidateBranch...$userName:$workingBranch?expand=1'),
      );
      expect(
          Uri.decodeQueryComponent(
              titlePattern.firstMatch(link)?.group(1) ?? ''),
          '[flutter_releases] Flutter $releaseChannel $releaseVersion Framework Cherrypicks');
      final String expectedBody = '''
# Flutter $releaseChannel $releaseVersion Framework

## Scheduled Cherrypicks

- commit: ${frameworkCherrypick.substring(0, 9)}
''';
      expect(
        Uri.decodeQueryComponent(bodyPattern.firstMatch(link)?.group(1) ?? ''),
        expectedBody,
      );
    });
  });

  group('getBoolFromEnvOrArgs', () {
    const String flagName = 'a-cli-flag';

    test('prefers env over argResults', () {
      final ArgResults argResults = FakeArgs(results: <String, Object>{
        flagName: false,
      });
      final Map<String, String> env = <String, String>{'A_CLI_FLAG': 'TRUE'};
      final bool result = getBoolFromEnvOrArgs(
        flagName,
        argResults,
        env,
      );
      expect(result, true);
    });

    test('falls back to argResults if env is empty', () {
      final ArgResults argResults = FakeArgs(results: <String, Object>{
        flagName: false,
      });
      final Map<String, String> env = <String, String>{};
      final bool result = getBoolFromEnvOrArgs(
        flagName,
        argResults,
        env,
      );
      expect(result, false);
    });
  });
}

class FakeArgs implements ArgResults {
  FakeArgs({
    this.arguments = const <String>[],
    this.name = 'fake-command',
    this.results = const <String, Object>{},
  });

  final Map<String, Object> results;

  @override
  final List<String> arguments;

  @override
  final String name;

  @override
  ArgResults? get command => throw Exception('Unimplemented');

  @override
  List<String> get rest => throw Exception('Unimplemented');

  @override
  Iterable<String> get options => throw Exception('Unimplemented');

  @override
  bool wasParsed(String name) {
    return results[name] != null;
  }

  @override
  Object? operator[](String name) {
    return results[name];
  }
}
