// 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/file.dart';
import 'package:file/memory.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';

import 'package:flutter_devicelab/framework/cocoon.dart';
import 'package:flutter_devicelab/framework/task_result.dart';

import 'common.dart';

void main() {
  ProcessResult _processResult;
  ProcessResult runSyncStub(String executable, List<String> args,
          {Map<String, String> environment,
          bool includeParentEnvironment,
          bool runInShell,
          Encoding stderrEncoding,
          Encoding stdoutEncoding,
          String workingDirectory}) =>
      _processResult;

  // Expected test values.
  const String commitSha = 'a4952838bf288a81d8ea11edfd4b4cd649fa94cc';
  const String serviceAccountTokenPath = 'test_account_file';
  const String serviceAccountToken = 'test_token';

  group('Cocoon', () {
    Client mockClient;
    Cocoon cocoon;
    FileSystem fs;

    setUp(() {
      fs = MemoryFileSystem();
      mockClient = MockClient((Request request) async => Response('{}', 200));

      final File serviceAccountFile = fs.file(serviceAccountTokenPath)..createSync();
      serviceAccountFile.writeAsStringSync(serviceAccountToken);
    });

    test('returns expected commit sha', () {
      _processResult = ProcessResult(1, 0, commitSha, '');
      cocoon = Cocoon(
        serviceAccountTokenPath: serviceAccountTokenPath,
        fs: fs,
        httpClient: mockClient,
        processRunSync: runSyncStub,
      );

      expect(cocoon.commitSha, commitSha);
    });

    test('throws exception on git cli errors', () {
      _processResult = ProcessResult(1, 1, '', '');
      cocoon = Cocoon(
        serviceAccountTokenPath: serviceAccountTokenPath,
        fs: fs,
        httpClient: mockClient,
        processRunSync: runSyncStub,
      );

      expect(() => cocoon.commitSha, throwsA(isA<CocoonException>()));
    });

    test('writes expected update task json', () async {
      _processResult = ProcessResult(1, 0, commitSha, '');
      final TaskResult result = TaskResult.fromJson(<String, dynamic>{
        'success': true,
        'data': <String, dynamic>{
          'i': 0,
          'j': 0,
          'not_a_metric': 'something',
        },
        'benchmarkScoreKeys': <String>['i', 'j'],
      });

      cocoon = Cocoon(
        fs: fs,
        processRunSync: runSyncStub,
      );

      const String resultsPath = 'results.json';
      await cocoon.writeTaskResultToFile(
        builderName: 'builderAbc',
        gitBranch: 'master',
        result: result,
        resultsPath: resultsPath,
      );

      final String resultJson = fs.file(resultsPath).readAsStringSync();
      const String expectedJson = '{'
          '"CommitBranch":"master",'
          '"CommitSha":"$commitSha",'
          '"BuilderName":"builderAbc",'
          '"NewStatus":"Succeeded",'
          '"ResultData":{"i":0.0,"j":0.0,"not_a_metric":"something"},'
          '"BenchmarkScoreKeys":["i","j"]}';
      expect(resultJson, expectedJson);
    });

    test('uploads expected update task payload from results file', () async {
      _processResult = ProcessResult(1, 0, commitSha, '');
      cocoon = Cocoon(
        fs: fs,
        httpClient: mockClient,
        processRunSync: runSyncStub,
        serviceAccountTokenPath: serviceAccountTokenPath,
      );

      const String resultsPath = 'results.json';
      const String updateTaskJson = '{'
          '"CommitBranch":"master",'
          '"CommitSha":"$commitSha",'
          '"BuilderName":"builderAbc",'
          '"NewStatus":"Succeeded",'
          '"ResultData":{"i":0.0,"j":0.0,"not_a_metric":"something"},'
          '"BenchmarkScoreKeys":["i","j"]}';
      fs.file(resultsPath).writeAsStringSync(updateTaskJson);
      await cocoon.sendResultsPath(resultsPath);
    });

    test('sends expected request from successful task', () async {
      mockClient = MockClient((Request request) async => Response('{}', 200));

      cocoon = Cocoon(
        serviceAccountTokenPath: serviceAccountTokenPath,
        fs: fs,
        httpClient: mockClient,
      );

      final TaskResult result = TaskResult.success(<String, dynamic>{});
      // This should not throw an error.
      await cocoon.sendTaskResult(builderName: 'builderAbc', gitBranch: 'branchAbc', result: result);
    });

    test('throws client exception on non-200 responses', () async {
      mockClient = MockClient((Request request) async => Response('', 500));

      cocoon = Cocoon(
        serviceAccountTokenPath: serviceAccountTokenPath,
        fs: fs,
        httpClient: mockClient,
      );

      final TaskResult result = TaskResult.success(<String, dynamic>{});
      expect(() => cocoon.sendTaskResult(builderName: 'builderAbc', gitBranch: 'branchAbc', result: result),
          throwsA(isA<ClientException>()));
    });

    test('null git branch throws error', () async {
      mockClient = MockClient((Request request) async => Response('', 500));

      cocoon = Cocoon(
        serviceAccountTokenPath: serviceAccountTokenPath,
        fs: fs,
        httpClient: mockClient,
      );

      final TaskResult result = TaskResult.success(<String, dynamic>{});
      expect(() => cocoon.sendTaskResult(builderName: 'builderAbc', gitBranch: null, result: result),
          throwsA(isA<AssertionError>()));
    });
  });

  group('AuthenticatedCocoonClient', () {
    FileSystem fs;

    setUp(() {
      fs = MemoryFileSystem();
      final File serviceAccountFile = fs.file(serviceAccountTokenPath)..createSync();
      serviceAccountFile.writeAsStringSync(serviceAccountToken);
    });

    test('reads token from service account file', () {
      final AuthenticatedCocoonClient client = AuthenticatedCocoonClient(serviceAccountTokenPath, filesystem: fs);
      expect(client.serviceAccountToken, serviceAccountToken);
    });

    test('reads token from service account file with whitespace', () {
      final File serviceAccountFile = fs.file(serviceAccountTokenPath)..createSync();
      serviceAccountFile.writeAsStringSync(serviceAccountToken + ' \n');
      final AuthenticatedCocoonClient client = AuthenticatedCocoonClient(serviceAccountTokenPath, filesystem: fs);
      expect(client.serviceAccountToken, serviceAccountToken);
    });

    test('throws error when service account file not found', () {
      final AuthenticatedCocoonClient client = AuthenticatedCocoonClient('idontexist', filesystem: fs);
      expect(() => client.serviceAccountToken, throwsA(isA<FileSystemException>()));
    });
  });
}
