// Copyright 2019 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 'package:cocoon_service/src/model/appengine/commit.dart';
import 'package:cocoon_service/src/model/appengine/stage.dart';
import 'package:cocoon_service/src/request_handlers/get_status.dart';
import 'package:cocoon_service/src/request_handling/body.dart';
import 'package:cocoon_service/src/service/build_status_provider.dart';
import 'package:cocoon_service/src/service/datastore.dart';
import 'package:gcloud/db.dart';
import 'package:test/test.dart';

import '../src/datastore/fake_config.dart';
import '../src/request_handling/fake_authentication.dart';
import '../src/request_handling/fake_http.dart';
import '../src/request_handling/request_handler_tester.dart';
import '../src/service/fake_build_status_provider.dart';

void main() {
  group('GetStatus', () {
    late FakeConfig config;
    FakeClientContext clientContext;
    FakeKeyHelper keyHelper;
    FakeBuildStatusService buildStatusService;
    late RequestHandlerTester tester;
    late GetStatus handler;

    late Commit commit1;
    late Commit commit2;

    Future<T?> decodeHandlerBody<T>() async {
      final Body body = await tester.get(handler);
      return await utf8.decoder.bind(body.serialize() as Stream<List<int>>).transform(json.decoder).single as T?;
    }

    setUp(() {
      clientContext = FakeClientContext();
      keyHelper = FakeKeyHelper(applicationContext: clientContext.applicationContext);
      tester = RequestHandlerTester();
      config = FakeConfig(keyHelperValue: keyHelper);
      buildStatusService = FakeBuildStatusService(commitStatuses: <CommitStatus>[]);
      handler = GetStatus(
        config,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
        buildStatusProvider: (_) => buildStatusService,
      );
      commit1 = Commit(
          key: config.db.emptyKey.append(Commit, id: 'flutter/flutter/ea28a9c34dc701de891eaf74503ca4717019f829'),
          repository: 'flutter/flutter',
          sha: 'ea28a9c34dc701de891eaf74503ca4717019f829',
          timestamp: 3,
          message: 'test message 1',
          branch: 'master');
      commit2 = Commit(
          key: config.db.emptyKey.append(Commit, id: 'flutter/flutter/d5b0b3c8d1c5fd89302089077ccabbcfaae045e4'),
          repository: 'flutter/flutter',
          sha: 'd5b0b3c8d1c5fd89302089077ccabbcfaae045e4',
          timestamp: 1,
          message: 'test message 2',
          branch: 'master');
    });

    test('no statuses', () async {
      final Map<String, dynamic> result = (await decodeHandlerBody())!;
      expect(result['Statuses'], isEmpty);
    });

    test('reports statuses without input commit key', () async {
      config.db.values[commit1.key] = commit1;
      config.db.values[commit2.key] = commit2;
      buildStatusService = FakeBuildStatusService(commitStatuses: <CommitStatus>[
        CommitStatus(commit1, const <Stage>[]),
        CommitStatus(commit2, const <Stage>[])
      ]);
      handler = GetStatus(
        config,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
        buildStatusProvider: (_) => buildStatusService,
      );

      final Map<String, dynamic> result = (await decodeHandlerBody())!;

      expect(result['Statuses'].length, 2);
    });

    test('reports statuses with input commit key', () async {
      final Commit commit1 = Commit(
          key: config.db.emptyKey.append(Commit, id: 'flutter/flutter/ea28a9c34dc701de891eaf74503ca4717019f829'),
          repository: 'flutter/flutter',
          sha: 'ea28a9c34dc701de891eaf74503ca4717019f829',
          timestamp: 3,
          message: 'test message 1',
          branch: 'master');
      final Commit commit2 = Commit(
          key: config.db.emptyKey.append(Commit, id: 'flutter/flutter/d5b0b3c8d1c5fd89302089077ccabbcfaae045e4'),
          repository: 'flutter/flutter',
          sha: 'd5b0b3c8d1c5fd89302089077ccabbcfaae045e4',
          timestamp: 1,
          message: 'test message 2',
          branch: 'master');
      config.db.values[commit1.key] = commit1;
      config.db.values[commit2.key] = commit2;
      buildStatusService = FakeBuildStatusService(commitStatuses: <CommitStatus>[
        CommitStatus(commit1, const <Stage>[]),
        CommitStatus(commit2, const <Stage>[])
      ]);
      handler = GetStatus(
        config,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
        buildStatusProvider: (_) => buildStatusService,
      );

      const String expectedLastCommitKeyEncoded =
          'ahNzfmZsdXR0ZXItZGFzaGJvYXJkckcLEglDaGVja2xpc3QiOGZsdXR0ZXIvZmx1dHRlci9lYTI4YTljMzRkYzcwMWRlODkxZWFmNzQ1MDNjYTQ3MTcwMTlmODI5DA';

      tester.request = FakeHttpRequest(queryParametersValue: <String, String>{
        GetStatus.kLastCommitKeyParam: expectedLastCommitKeyEncoded,
      });
      final Map<String, dynamic> result = (await decodeHandlerBody())!;

      expect(result['Statuses'].first, <String, dynamic>{
        'Checklist': <String, dynamic>{
          'Key':
              'ahFmbHV0dGVyLWRhc2hib2FyZHJHCxIJQ2hlY2tsaXN0IjhmbHV0dGVyL2ZsdXR0ZXIvZDViMGIzYzhkMWM1ZmQ4OTMwMjA4OTA3N2NjYWJiY2ZhYWUwNDVlNAyiAQlbZGVmYXVsdF0',
          'Checklist': <String, dynamic>{
            'FlutterRepositoryPath': 'flutter/flutter',
            'CreateTimestamp': 1,
            'Commit': <String, dynamic>{
              'Sha': 'd5b0b3c8d1c5fd89302089077ccabbcfaae045e4',
              'Message': 'test message 2',
              'Author': <String, dynamic>{'Login': null, 'avatar_url': null}
            },
            'Branch': 'master'
          }
        },
        'Stages': <String>[]
      });
    });

    test('reports statuses with input branch', () async {
      commit2.branch = 'flutter-1.1-candidate.1';
      config.db.values[commit1.key] = commit1;
      config.db.values[commit2.key] = commit2;
      buildStatusService = FakeBuildStatusService(commitStatuses: <CommitStatus>[
        CommitStatus(commit1, const <Stage>[]),
        CommitStatus(commit2, const <Stage>[])
      ]);
      handler = GetStatus(
        config,
        datastoreProvider: (DatastoreDB db) => DatastoreService(config.db, 5),
        buildStatusProvider: (_) => buildStatusService,
      );

      const String branch = 'flutter-1.1-candidate.1';

      expect(config.db.values.length, 2);

      tester.request = FakeHttpRequest(queryParametersValue: <String, String>{
        GetStatus.kBranchParam: branch,
      });
      final Map<String, dynamic> result = (await decodeHandlerBody())!;

      expect(result['Statuses'].length, 1);
      expect(result['Statuses'].first, <String, dynamic>{
        'Checklist': <String, dynamic>{
          'Key':
              'ahFmbHV0dGVyLWRhc2hib2FyZHJHCxIJQ2hlY2tsaXN0IjhmbHV0dGVyL2ZsdXR0ZXIvZDViMGIzYzhkMWM1ZmQ4OTMwMjA4OTA3N2NjYWJiY2ZhYWUwNDVlNAyiAQlbZGVmYXVsdF0',
          'Checklist': <String, dynamic>{
            'FlutterRepositoryPath': 'flutter/flutter',
            'CreateTimestamp': 1,
            'Commit': <String, dynamic>{
              'Sha': 'd5b0b3c8d1c5fd89302089077ccabbcfaae045e4',
              'Message': 'test message 2',
              'Author': <String, dynamic>{'Login': null, 'avatar_url': null}
            },
            'Branch': 'flutter-1.1-candidate.1'
          }
        },
        'Stages': <String>[]
      });
    });
  });
}
