// 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:io';

import 'package:github/github.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:path/path.dart' as p;
import 'package:symbolizer/bot.dart';
import 'package:symbolizer/config.dart';
import 'package:symbolizer/model.dart';
import 'package:symbolizer/ndk.dart';
import 'package:symbolizer/symbols.dart';
import 'package:test/test.dart';

import 'package:symbolizer/symbolizer.dart';

@GenerateNiceMocks([
  MockSpec<GitHub>(),
  MockSpec<IssuesService>(),
])
import 'bot_test.mocks.dart';

class SymbolsCacheProxy implements SymbolsCache {
  final SymbolsCache impl;
  final bool shouldThrow;
  SymbolsCacheProxy(this.impl, {this.shouldThrow = false});

  @override
  Future<EngineBuild> findVariantByBuildId(
      {required String engineHash,
      required EngineVariant variant,
      String? buildId}) {
    return impl.findVariantByBuildId(
        engineHash: engineHash, variant: variant, buildId: buildId);
  }

  @override
  Future<String> get(EngineBuild build) {
    if (shouldThrow) {
      throw 'Failed to download $build';
    }
    return impl.get(build);
  }

  @override
  Future<String> getEngineBinary(EngineBuild build) =>
      impl.getEngineBinary(build);
}

final regenerateExpectations =
    bool.fromEnvironment('REGENERATE_EXPECTATIONS') ||
        Platform.environment['REGENERATE_EXPECTATIONS'] == 'true';

final config = loadConfigFromFile();

void main() {
  group('command parsing', () {
    test('nothing to do', () {
      expect(Bot.parseCommand(0, 'x64'), isNull);
      expect(Bot.parseCommand(0, 'x64 debug'), isNull);
      expect(Bot.parseCommand(0, 'x64\n@flutter-symbolizer-bot'), isNull);
    });
    test('simple', () {
      expect(
          Bot.parseCommand(0, '@flutter-symbolizer-bot'),
          equals(BotCommand(
            overrides: SymbolizationOverrides(),
            symbolizeThis: false,
            worklist: <String>{},
          )));
    });
    test('with arch', () {
      for (var arch in ['arm', 'arm64', 'x86', 'x64']) {
        expect(
            Bot.parseCommand(0, '@flutter-symbolizer-bot $arch'),
            equals(BotCommand(
              overrides: SymbolizationOverrides(arch: arch),
              symbolizeThis: false,
              worklist: <String>{},
            )));
      }
    });
    test('with mode', () {
      for (var mode in ['profile', 'release', 'debug']) {
        expect(
            Bot.parseCommand(0, '@flutter-symbolizer-bot $mode'),
            equals(BotCommand(
              overrides: SymbolizationOverrides(mode: mode),
              symbolizeThis: false,
              worklist: <String>{},
            )));
      }
    });
    test('with engine hash', () {
      expect(
          Bot.parseCommand(
              0, '@flutter-symbolizer-bot arm64 engine#aaabbb debug'),
          equals(BotCommand(
            overrides: SymbolizationOverrides(
                arch: 'arm64', engineHash: 'aaabbb', mode: 'debug'),
            symbolizeThis: false,
            worklist: <String>{},
          )));
    });
    test('with links', () {
      expect(
          Bot.parseCommand(
              0,
              '@flutter-symbolizer-bot '
              'https://github.com/flutter/flutter/issues/0#issue-1 '
              'engine#aaabbb '
              'https://github.com/flutter/flutter/issues/0#issuecomment-2'),
          equals(BotCommand(
            overrides: SymbolizationOverrides(engineHash: 'aaabbb'),
            symbolizeThis: false,
            worklist: <String>{'issue-1', 'issuecomment-2'},
          )));
    });
  });

  group('end-to-end', () {
    late SymbolsCache symbols;
    late Ndk ndk;
    late GitHub github;
    final files = Directory('test/data').listSync();

    setUpAll(() {
      ndk = Ndk();
      symbols = SymbolsCache(path: 'symbols-cache', ndk: ndk);
      github = GitHub(auth: Authentication.withToken(config.githubToken));
    });

    for (var inputFile in files
        .where((f) => p.basename(f.path).endsWith('.input.txt'))
        .cast<File>()) {
      final testName = p.basename(inputFile.path).split('.').first;
      final expectationFile = File('test/data/$testName.expected.github.txt');
      test(testName, () async {
        final input = await inputFile.readAsString();

        final authorized = !input.contains('/unauthorized');
        final shouldThrow = input.contains('/throw');

        final symbolsProxy =
            SymbolsCacheProxy(symbols, shouldThrow: shouldThrow);

        final symbolizer =
            Symbolizer(symbols: symbolsProxy, ndk: ndk, github: github);

        final mockGitHub = MockGitHub();
        final mockIssues = MockIssuesService();
        final repo = RepositorySlug('flutter', 'flutter');
        final bot = Bot(
          github: mockGitHub,
          symbolizer: symbolizer,
          failuresEmail: null,
          mailer: null,
        );

        final command = Bot.isCommand(input)
            ? Bot.parseCommand(0, input)!.symbolizeThis
                ? input
                : input.split('\n').first
            : Bot.accountMention;

        final somebody = User(login: 'somebody');
        final commandComment = IssueComment(
            id: 1001,
            body: command,
            user: somebody,
            htmlUrl:
                'https://github.com/flutter/flutter/issues/12345#issuecomment-1001');

        when(mockGitHub.issues).thenReturn(mockIssues);

        when(mockIssues.listCommentsByIssue(repo, 42))
            .thenAnswer((realInvocation) async* {
          yield IssueComment(
              id: 1002,
              body: 'something',
              user: somebody,
              htmlUrl:
                  'https://github.com/flutter/flutter/issues/12345#issuecomment-1002');
          yield IssueComment(
              id: 1042,
              body: input,
              user: somebody,
              htmlUrl:
                  'https://github.com/flutter/flutter/issues/12345#issuecomment-1042');
          yield commandComment;
        });

        when(mockIssues.createComment(repo, 42, any))
            .thenAnswer((realInvocation) async {
          return IssueComment();
        });

        throwOnMissingStub(mockGitHub);
        throwOnMissingStub(mockIssues);
        await bot.executeCommand(
          repo,
          Issue(id: 1000, body: 'something', number: 42),
          commandComment,
          authorized: authorized,
        );

        final result = verify(mockIssues.createComment(repo, 42, captureAny))
            .captured
            .single;

        if (regenerateExpectations) {
          await expectationFile.writeAsString(result);
        } else {
          final expected = await expectationFile.readAsString();

          expect(result, equals(expected));
        }
      });
    }

    tearDownAll(() {
      github.dispose();
    });
  });
}
