// 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/service/github_service.dart';
import 'package:github/github.dart';
import 'package:shelf/src/response.dart';

import '../../utilities/mocks.dart';

/// A fake GithubService implementation.
class FakeGithubService implements GithubService {
  FakeGithubService({
    MockGitHub? client,
    String? checkRunsMock,
    String? commitMock,
    String? pullRequest,
    String? compareTwoCommitsMock,
    String? successMergeMock,
    String? createCommentMock,
    String? pullRequestMergeMock,
  }) : github = client ?? MockGitHub();

  @override
  final MockGitHub github;

  String? checkRunsMock;
  String? commitMock;
  PullRequest? pullRequestMock;
  String? compareTwoCommitsMock;
  String? successMergeMock;
  String? createCommentMock;
  String? pullRequestMergeMock;
  String? pullRequestFilesJsonMock;
  Issue? githubIssueMock;

  bool useMergeRequestMockList = false;
  bool trackMergeRequestCalls = false;
  PullRequestMerge? mergeRequestMock;
  List<PullRequestMerge> pullRequestMergeMockList = [];

  /// map to track pull request calls using pull number and repository slug.
  Map<int, RepositorySlug> verifyPullRequestMergeCallMap = {};

  bool throwOnCreateIssue = false;

  /// Setting either of these flags to true will pop the front element from the
  /// list. Setting either to false will just return the non list version from
  /// the appropriate method.
  bool usePullRequestList = false;
  bool usePullRequestFilesList = false;

  List<String?> pullRequestFilesMockList = [];
  List<PullRequest?> pullRequestMockList = [];
  List<IssueComment> issueCommentsMockList = [];

  IssueComment? issueComment;
  bool useRealComment = false;
  bool labelRemoved = false;

  bool compareReturnValue = false;
  bool skipRealCompare = false;

  set checkRunsData(String? checkRunsMock) {
    this.checkRunsMock = checkRunsMock;
  }

  set commitData(String? commitMock) {
    this.commitMock = commitMock;
  }

  set pullRequestData(PullRequest? pullRequestMock) {
    this.pullRequestMock = pullRequestMock;
  }

  set compareTwoCommitsData(String? compareTwoCommitsMock) {
    this.compareTwoCommitsMock = compareTwoCommitsMock;
  }

  set successMergeData(String? successMergeMock) {
    this.successMergeMock = successMergeMock;
  }

  set createCommentData(String? createCommentMock) {
    this.createCommentMock = createCommentMock;
  }

  set pullRequestMergeData(String? pullRequestMergeMock) {
    this.pullRequestMergeMock = pullRequestMergeMock;
  }

  set pullrequestFilesData(String? pullRequestFilesMock) {
    pullRequestFilesJsonMock = pullRequestFilesMock;
  }

  set githubIssue(Issue? issue) {
    githubIssueMock = issue;
  }

  @override
  Future<List<CheckRun>> getCheckRuns(
    RepositorySlug slug,
    String ref,
  ) async {
    final rawBody = json.decode(checkRunsMock!) as Map<String, dynamic>;
    final List<dynamic> checkRunsBody = rawBody["check_runs"]! as List<dynamic>;
    final List<CheckRun> checkRuns = <CheckRun>[];
    if ((checkRunsBody[0] as Map<String, dynamic>).isNotEmpty) {
      checkRuns.addAll(
        checkRunsBody.map((dynamic checkRun) => CheckRun.fromJson(checkRun as Map<String, dynamic>)).toList(),
      );
    }
    return checkRuns;
  }

  @override
  Future<List<CheckRun>> getCheckRunsFiltered({
    required RepositorySlug slug,
    required String ref,
    String? checkName,
    CheckRunStatus? status,
    CheckRunFilter? filter,
  }) async {
    final List<CheckRun> checkRuns = await getCheckRuns(slug, ref);
    if (checkName != null) {
      final List<CheckRun> checkRunsFilteredByName = [];
      for (CheckRun checkRun in checkRuns) {
        if (checkRun.name == checkName) {
          checkRunsFilteredByName.add(checkRun);
        }
      }
      return checkRunsFilteredByName;
    }
    return checkRuns;
  }

  @override
  Future<RepositoryCommit> getCommit(RepositorySlug slug, String sha) async {
    final RepositoryCommit commit = RepositoryCommit.fromJson(jsonDecode(commitMock!) as Map<String, dynamic>);
    return commit;
  }

  @override
  Future<PullRequest> getPullRequest(RepositorySlug slug, int pullRequestNumber) async {
    PullRequest pullRequest;
    if (usePullRequestList && pullRequestMockList.isNotEmpty) {
      pullRequest = pullRequestMockList.removeAt(0)!;
    } else if (usePullRequestList && pullRequestMockList.isEmpty) {
      throw Exception('List is empty.');
    } else {
      pullRequest = pullRequestMock!;
    }
    return pullRequest;
  }

  @override
  Future<GitHubComparison> compareTwoCommits(RepositorySlug slug, String refBase, String refHead) async {
    final GitHubComparison githubComparison =
        GitHubComparison.fromJson(jsonDecode(compareTwoCommitsMock!) as Map<String, dynamic>);
    return githubComparison;
  }

  @override
  Future<bool> removeLabel(RepositorySlug slug, int issueNumber, String label) async {
    labelRemoved = true;
    return labelRemoved;
  }

  @override
  Future<IssueComment> createComment(RepositorySlug slug, int number, String commentBody) async {
    if (useRealComment) {
      issueComment = IssueComment(id: number, body: commentBody);
    } else {
      issueComment = IssueComment.fromJson(jsonDecode(createCommentMock!) as Map<String, dynamic>);
    }
    return issueComment!;
  }

  @override
  Future<bool> updateBranch(RepositorySlug slug, int number, String headSha) async {
    return true;
  }

  @override
  Future<Response> autoMergeBranch(PullRequest pullRequest) {
    // TODO: implement autoMergeBranch
    throw UnimplementedError();
  }

  @override
  Future<List<PullRequestFile>> getPullRequestFiles(RepositorySlug slug, PullRequest pullRequest) async {
    String pullRequestData;

    if (usePullRequestFilesList && pullRequestFilesMockList.isNotEmpty) {
      pullRequestData = pullRequestFilesMockList.removeAt(0)!;
    } else if (usePullRequestFilesList && pullRequestFilesMockList.isEmpty) {
      throw Exception('File list is empty.');
    } else {
      pullRequestData = pullRequestFilesJsonMock as String;
    }

    final List<PullRequestFile> pullRequestFileList = [];

    final dynamic parsedList = jsonDecode(pullRequestData);

    for (dynamic d in parsedList) {
      final PullRequestFile file = PullRequestFile.fromJson(d as Map<String, dynamic>);
      pullRequestFileList.add(file);
    }

    return pullRequestFileList;
  }

  @override
  Future<Issue> createIssue({
    required RepositorySlug slug,
    required String title,
    required String body,
    List<String>? labels,
    String? assignee,
    List<String>? assignees,
    String? state,
  }) async {
    if (throwOnCreateIssue) {
      throw GitHubError(github, 'Exception on github create issue.');
    }
    return githubIssueMock!;
  }

  @override
  Future<bool> comparePullRequests(RepositorySlug repositorySlug, PullRequest revert, PullRequest current) async {
    if (skipRealCompare) {
      return compareReturnValue;
    }

    final List<PullRequestFile> revertPullRequestFiles = await getPullRequestFiles(repositorySlug, revert);
    final List<PullRequestFile> currentPullRequestFiles = await getPullRequestFiles(repositorySlug, current);

    return validateFileSetsAreEqual(revertPullRequestFiles, currentPullRequestFiles);
  }

  @override
  bool validateFileSetsAreEqual(
    List<PullRequestFile> changeList1,
    List<PullRequestFile> changeList2,
  ) {
    if (changeList1.length != changeList2.length) {
      return false;
    }

    final List<String?> revertFileNames = [];
    final List<String?> currentFileNames = [];

    for (PullRequestFile element in changeList1) {
      revertFileNames.add(element.filename);
    }
    for (PullRequestFile element in changeList2) {
      currentFileNames.add(element.filename);
    }

    // At this point we know the file lists have the same amount of files but not the same files.
    if (!revertFileNames.toSet().containsAll(currentFileNames) ||
        !currentFileNames.toSet().containsAll(revertFileNames)) {
      return false;
    }

    // At this point all the files are the same so we can iterate over one list to
    // compare changes.
    for (PullRequestFile pullRequestFile in changeList1) {
      final PullRequestFile pullRequestFileChangeList2 =
          changeList2.firstWhere((element) => element.filename == pullRequestFile.filename);
      if (pullRequestFile.changesCount != pullRequestFileChangeList2.changesCount ||
          pullRequestFile.additionsCount != pullRequestFileChangeList2.deletionsCount ||
          pullRequestFile.deletionsCount != pullRequestFileChangeList2.additionsCount) {
        return false;
      }
    }

    return true;
  }

  @override
  Future<Issue> getIssue({required RepositorySlug slug, required int issueNumber}) async {
    return githubIssueMock!;
  }

  /// If useMergeRequestMockList is true then we will return elements from that
  /// list until it is empty.
  ///
  /// The developer should track the number of times this method is called as
  /// managing an empty list is not done here.
  @override
  Future<PullRequestMerge> mergePullRequest(
    RepositorySlug slug,
    int number, {
    String? commitMessage,
    MergeMethod? mergeMethod,
    String? requestSha,
  }) async {
    verifyPullRequestMergeCallMap[number] = slug;
    if (useMergeRequestMockList) {
      return pullRequestMergeMockList.removeAt(0);
    } else {
      return mergeRequestMock!;
    }
  }

  void verifyMergePullRequests(Map<int, RepositorySlug> expected) {
    assert(verifyPullRequestMergeCallMap.length == expected.length);
    verifyPullRequestMergeCallMap.forEach((key, value) {
      assert(expected.containsKey(key));
      assert(expected[key] == value);
    });
  }

  @override
  Future<List<IssueComment>> listIssueComments(RepositorySlug slug, int issueNumber) async {
    final List<IssueComment> issueCommentList = [];
    issueCommentList.addAll(issueCommentsMockList);
    return issueCommentList;
  }
}
