// Copyright 2022 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:auto_submit/exception/bigquery_exception.dart';
import 'package:auto_submit/model/big_query_pull_request_record.dart';
import 'package:auto_submit/model/big_query_revert_request_record.dart';
import 'package:googleapis/bigquery/v2.dart';
import 'package:mockito/mockito.dart';
import 'package:test/expect.dart';
import 'package:test/scaffolding.dart';

import '../src/service/fake_bigquery_service.dart';
import '../utilities/mocks.dart';

const String revertRequestRecordResponse = '''
{
  "jobComplete": true,
  "rows": [
    { "f": [
        { "v": "flutter"},
        { "v": "cocoon" },
        { "v": "ricardoamador" },
        { "v": "1024" },
        { "v": "123f124" },
        { "v": "123456789" },
        { "v": "123456999" },
        { "v": "ricardoamador" },
        { "v": "2048" },
        { "v": "ce345dc" },
        { "v": "234567890" },
        { "v": "234567999" },
        { "v": "ricardoamador" },
        { "v": "11304" },
        { "v": "1640979000000" },
        { "v": null }
      ]
    }
  ]
}
''';

const String pullRequestRecordResponse = '''
{
  "jobComplete": true,
  "rows": [
    { "f": [
        { "v": "123456789"},
        { "v": "234567890" },
        { "v": "flutter" },
        { "v": "cocoon" },
        { "v": "ricardoamador" },
        { "v": "345" },
        { "v": "ade456" },
        { "v": "merge" }
      ]
    }
  ]
}
''';

const String successResponseNoRowsAffected = '''
{
  "jobComplete": true
}
''';

const String insertDeleteSuccessResponse = '''
{
  "jobComplete": true,
  "numDmlAffectedRows": "1"
}
''';

const String insertDeleteSuccessTooManyRows = '''
{
  "jobComplete": true,
  "numDmlAffectedRows": "2"
}
''';

const String selectPullRequestTooManyRowsResponse = '''
{
  "jobComplete": true,
  "numDmlAffectedRows": "2",
  "rows": [
    { "f": [
        { "v": "123456789"},
        { "v": "234567890" },
        { "v": "flutter" },
        { "v": "cocoon" },
        { "v": "ricardoamador" },
        { "v": "345" },
        { "v": "ade456" },
        { "v": "merge" }
      ]
    },
    { "f": [
        { "v": "123456789"},
        { "v": "234567890" },
        { "v": "flutter" },
        { "v": "cocoon" },
        { "v": "ricardoamador" },
        { "v": "345" },
        { "v": "ade456" },
        { "v": "merge" }
      ]
    }
  ]
}
''';

const String selectRevertRequestTooManyRowsResponse = '''
{
  "jobComplete": true,
  "numDmlAffectedRows": "2",
  "rows": [
    { "f": [
        { "v": "flutter"},
        { "v": "cocoon" },
        { "v": "ricardoamador" },
        { "v": "1024" },
        { "v": "123f124" },
        { "v": "123456789" },
        { "v": "123456999" },
        { "v": "ricardoamador" },
        { "v": "2048" },
        { "v": "ce345dc" },
        { "v": "234567890" },
        { "v": "234567999" }
      ]
    },
    { "f": [
        { "v": "flutter"},
        { "v": "cocoon" },
        { "v": "ricardoamador" },
        { "v": "1024" },
        { "v": "123f124" },
        { "v": "123456789" },
        { "v": "123456999" },
        { "v": "ricardoamador" },
        { "v": "2048" },
        { "v": "ce345dc" },
        { "v": "234567890" },
        { "v": "234567999" }
      ]
    }
  ]
}
''';

const String errorResponse = '''
{
  "jobComplete": false
}
''';

const String expectedProjectId = 'flutter-dashboard';

void main() {
  late FakeBigqueryService service;
  late MockJobsResource jobsResource;

  setUp(() {
    jobsResource = MockJobsResource();
    service = FakeBigqueryService(jobsResource);
  });

  test('Insert pull request record is successful.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessResponse) as Map<dynamic, dynamic>),
      );
    });

    PullRequestRecord pullRequestRecord = PullRequestRecord(
      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
      organization: 'flutter',
      repository: 'cocoon',
      author: 'ricardoamador',
      prNumber: 345,
      prCommit: 'ade456',
      prRequestType: 'merge',
    );

    bool hasError = false;
    try {
      await service.insertPullRequestRecord(
        projectId: expectedProjectId,
        pullRequestRecord: pullRequestRecord,
      );
    } on BigQueryException {
      hasError = true;
    }
    expect(hasError, isFalse);
  });

  test('Insert pull request record handles unsuccessful job complete error.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    PullRequestRecord pullRequestRecord = PullRequestRecord(
      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
      organization: 'flutter',
      repository: 'cocoon',
      author: 'ricardoamador',
      prNumber: 345,
      prCommit: 'ade456',
      prRequestType: 'merge',
    );

    try {
      await service.insertPullRequestRecord(
        projectId: expectedProjectId,
        pullRequestRecord: pullRequestRecord,
      );
    } on BigQueryException catch (exception) {
      expect(exception.cause, 'Insert pull request $pullRequestRecord did not complete.');
      hasError = true;
    }
    expect(hasError, isTrue);
  });

  test('Insert pull request fails when multiple rows are returned.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(selectPullRequestTooManyRowsResponse) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    PullRequestRecord pullRequestRecord = PullRequestRecord(
      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
      organization: 'flutter',
      repository: 'cocoon',
      author: 'ricardoamador',
      prNumber: 345,
      prCommit: 'ade456',
      prRequestType: 'merge',
    );

    try {
      await service.insertPullRequestRecord(
        projectId: expectedProjectId,
        pullRequestRecord: pullRequestRecord,
      );
    } on BigQueryException catch (exception) {
      expect(exception.cause, 'There was an error inserting $pullRequestRecord into the table.');
      hasError = true;
    }
    expect(hasError, isTrue);
  });

  test('Select pull request is successful.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(pullRequestRecordResponse) as Map<dynamic, dynamic>),
      );
    });

    PullRequestRecord pullRequestRecord = await service.selectPullRequestRecordByPrNumber(
      projectId: expectedProjectId,
      prNumber: 345,
      repository: 'cocoon',
    );

    expect(pullRequestRecord, isNotNull);
    expect(pullRequestRecord.prCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(123456789)));
    expect(pullRequestRecord.prLandedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(234567890)));
    expect(pullRequestRecord.organization, equals('flutter'));
    expect(pullRequestRecord.repository, equals('cocoon'));
    expect(pullRequestRecord.author, equals('ricardoamador'));
    expect(pullRequestRecord.prNumber, 345);
    expect(pullRequestRecord.prCommit, equals('ade456'));
    expect(pullRequestRecord.prRequestType, equals('merge'));
  });

  test('Select pull request handles unsuccessful job failure.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>));
    });

    bool hasError = false;
    try {
      await service.selectPullRequestRecordByPrNumber(
        projectId: expectedProjectId,
        prNumber: 345,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(exception.cause, 'Get pull request by pr# 345 in repository cocoon did not complete.');
    }
    expect(hasError, isTrue);
  });

  test('Select pull request handles no rows returned failure.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.selectPullRequestRecordByPrNumber(
        projectId: expectedProjectId,
        prNumber: 345,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'Could not find an entry for pull request with pr# 345 in repository cocoon.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Select pull request handles too many rows returned failure.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(selectPullRequestTooManyRowsResponse) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.selectPullRequestRecordByPrNumber(
        projectId: expectedProjectId,
        prNumber: 345,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'More than one record was returned for pull request with pr# 345 in repository cocoon.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Delete pull request record handles failure to complete job.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>));
    });

    bool hasError = false;
    try {
      await service.deletePullRequestRecord(
        projectId: expectedProjectId,
        prNumber: 345,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'Delete pull request with pr# 345 in repository cocoon did not complete.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Delete pull request record handles success but no affected rows.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.deletePullRequestRecord(
        projectId: expectedProjectId,
        prNumber: 345,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'Could not find pull request with pr# 345 in repository cocoon to delete.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Delete pull request record handles success but wrong number of affected rows.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessTooManyRows) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.deletePullRequestRecord(
        projectId: expectedProjectId,
        prNumber: 345,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'More than one row was deleted from the database for pull request with pr# 345 in repository cocoon.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Insert revert request record is successful.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessResponse) as Map<dynamic, dynamic>),
      );
    });

    RevertRequestRecord revertRequestRecord = RevertRequestRecord(
      organization: 'flutter',
      repository: 'cocoon',
      author: 'ricardoamador',
      prNumber: 1024,
      prCommit: '123f124',
      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456999),
      originalPrAuthor: 'ricardoamador',
      originalPrNumber: 1000,
      originalPrCommit: 'ce345dc',
      originalPrCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
      originalPrLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567999),
      reviewIssueAssignee: 'ricardoamador',
      reviewIssueNumber: 11304,
      reviewIssueCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(1640979000000),
    );

    bool hasError = false;
    try {
      await service.insertRevertRequestRecord(
        projectId: expectedProjectId,
        revertRequestRecord: revertRequestRecord,
      );
    } on BigQueryException {
      hasError = true;
    }
    expect(hasError, isFalse);
  });

  test('Insert revert request record handles unsuccessful job complete error.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    RevertRequestRecord revertRequestRecord = RevertRequestRecord(
      organization: 'flutter',
      repository: 'cocoon',
      author: 'ricardoamador',
      prNumber: 1024,
      prCommit: '123f124',
      prCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456789),
      prLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(123456999),
      originalPrAuthor: 'ricardoamador',
      originalPrNumber: 1000,
      originalPrCommit: 'ce345dc',
      originalPrCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567890),
      originalPrLandedTimestamp: DateTime.fromMillisecondsSinceEpoch(234567999),
      reviewIssueAssignee: 'ricardoamador',
      reviewIssueNumber: 11304,
      reviewIssueCreatedTimestamp: DateTime.fromMillisecondsSinceEpoch(1640979000000),
    );

    try {
      await service.insertRevertRequestRecord(
        projectId: expectedProjectId,
        revertRequestRecord: revertRequestRecord,
      );
    } on BigQueryException catch (e) {
      expect(e.cause, 'Insert revert request $revertRequestRecord did not complete.');
      hasError = true;
    }
    expect(hasError, isTrue);
  });

  test('Select revert request is successful.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(revertRequestRecordResponse) as Map<dynamic, dynamic>),
      );
    });

    RevertRequestRecord revertRequestRecord = await service.selectRevertRequestByRevertPrNumber(
      projectId: expectedProjectId,
      prNumber: 2048,
      repository: 'cocoon',
    );

    expect(revertRequestRecord, isNotNull);
    expect(revertRequestRecord.organization, equals('flutter'));
    expect(revertRequestRecord.repository, equals('cocoon'));
    expect(revertRequestRecord.author, equals('ricardoamador'));
    expect(revertRequestRecord.prNumber, equals(1024));
    expect(revertRequestRecord.prCommit, equals('123f124'));
    expect(revertRequestRecord.prCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(123456789)));
    expect(revertRequestRecord.prLandedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(123456999)));
    expect(revertRequestRecord.originalPrAuthor, equals('ricardoamador'));
    expect(revertRequestRecord.originalPrNumber, equals(2048));
    expect(revertRequestRecord.originalPrCommit, equals('ce345dc'));
    expect(revertRequestRecord.originalPrCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(234567890)));
    expect(revertRequestRecord.originalPrLandedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(234567999)));
    // { "v": "ricardoamador" },
    //     { "v": "11304" },
    //     { "v": "1640979000000" },
    //     { "v": null },
    expect(revertRequestRecord.reviewIssueAssignee, equals('ricardoamador'));
    expect(revertRequestRecord.reviewIssueNumber, equals(11304));
    expect(revertRequestRecord.reviewIssueCreatedTimestamp, equals(DateTime.fromMillisecondsSinceEpoch(1640979000000)));
    expect(revertRequestRecord.reviewIssueLandedTimestamp, isNull);
  });

  test('Select revert request is unsuccessful with job did not complete error.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.selectRevertRequestByRevertPrNumber(
        projectId: expectedProjectId,
        prNumber: 2048,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(exception.cause, 'Get revert request with pr# 2048 in repository cocoon did not complete.');
    }
    expect(hasError, isTrue);
  });

  test('Select revert request is successful but does not return any rows.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.selectRevertRequestByRevertPrNumber(
        projectId: expectedProjectId,
        prNumber: 2048,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'Could not find an entry for revert request with pr# 2048 in repository cocoon.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Select is successful but returns more than one row in the request.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(selectRevertRequestTooManyRowsResponse) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.selectRevertRequestByRevertPrNumber(
        projectId: expectedProjectId,
        prNumber: 2048,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'More than one record was returned for revert request with pr# 2048 in repository cocoon.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Delete revert request record handles failure to complete job.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(errorResponse) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.deleteRevertRequestRecord(
        projectId: expectedProjectId,
        prNumber: 2048,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'Delete revert request with pr# 2048 in repository cocoon did not complete.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Delete revert request record handles success but no affected rows.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(successResponseNoRowsAffected) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.deleteRevertRequestRecord(
        projectId: expectedProjectId,
        prNumber: 2048,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'Could not find revert request with pr# 2048 in repository cocoon to delete.',
      );
    }
    expect(hasError, isTrue);
  });

  test('Delete revert request record handles success but wrong number of affected rows.', () async {
    when(jobsResource.query(captureAny, expectedProjectId)).thenAnswer((Invocation invocation) {
      return Future<QueryResponse>.value(
        QueryResponse.fromJson(jsonDecode(insertDeleteSuccessTooManyRows) as Map<dynamic, dynamic>),
      );
    });

    bool hasError = false;
    try {
      await service.deleteRevertRequestRecord(
        projectId: expectedProjectId,
        prNumber: 2048,
        repository: 'cocoon',
      );
    } on BigQueryException catch (exception) {
      hasError = true;
      expect(
        exception.cause,
        'More than one row was deleted from the database for revert request with pr# 2048 in repository cocoon.',
      );
    }
    expect(hasError, isTrue);
  });
}
