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

import 'package:github/github.dart';
import 'package:http/http.dart';

import '../service/logging.dart';

class GithubService {
  GithubService(this.github);

  final GitHub github;
  static final Map<String, String> headers = <String, String>{'Accept': 'application/vnd.github.groot-preview+json'};
  static const String kRefsPrefix = 'refs/heads/';

  /// Lists commits of the provided repository [slug] and [branch]. When
  /// [lastCommitTimestampMills] equals 0, it means a new release branch is
  /// found and only the branched commit will be returned for now, though the
  /// rare case that multiple commits exist. For other cases, it returns all
  /// newer commits since [lastCommitTimestampMills].
  Future<List<RepositoryCommit>> listCommits(RepositorySlug slug, String branch, int? lastCommitTimestampMills) async {
    ArgumentError.checkNotNull(slug);
    final PaginationHelper paginationHelper = PaginationHelper(github);

    /// The [pages] defines the number of pages of returned http request
    /// results. Return only one page when this is a new branch. Otherwise
    ///  it will return all commits prior to this release branch commit,
    /// leading to heavy workload.
    int? pages;
    if (lastCommitTimestampMills == null || lastCommitTimestampMills == 0) {
      pages = 1;
    }

    List<Map<String, dynamic>> commits = <Map<String, dynamic>>[];

    /// [lastCommitTimestamp+1] excludes last commit itself.
    /// Github api url: https://developer.github.com/v3/repos/commits/#list-commits
    await for (Response response in paginationHelper.fetchStreamed(
      'GET',
      '/repos/${slug.fullName}/commits',
      params: <String, dynamic>{
        'sha': branch,
        'since': DateTime.fromMillisecondsSinceEpoch((lastCommitTimestampMills ?? 0) + 1).toUtc().toIso8601String(),
      },
      pages: pages,
      headers: headers,
    )) {
      commits.addAll((json.decode(response.body) as List<dynamic>).cast<Map<String, dynamic>>());
    }

    /// When a release branch is first detected only the most recent commit would be needed.
    ///
    /// If for the worst case, a new release branch consists of a useful cherry pick commit
    /// which should be considered as well, here is the todo.
    // TODO(keyonghan): https://github.com/flutter/flutter/issues/59275
    if (lastCommitTimestampMills == 0) {
      commits = commits.take(1).toList();
    }

    return commits.map<RepositoryCommit>((Map<String, dynamic> commit) {
      return RepositoryCommit()
        ..sha = commit['sha'] as String?
        ..author = (User()
          ..login = commit['author']['login'] as String?
          ..avatarUrl = commit['author']['avatar_url'] as String?)
        ..commit = (GitCommit()
          ..message = commit['commit']['message'] as String?
          ..committer = (GitCommitUser(
            commit['commit']['author']['name'] as String?,
            commit['commit']['author']['email'] as String?,
            DateTime.parse(commit['commit']['author']['date'] as String),
          )));
    }).toList();
  }

  /// List pull requests in the repository.
  Future<List<PullRequest>> listPullRequests(RepositorySlug slug, String? branch) {
    ArgumentError.checkNotNull(slug);
    return github.pullRequests
        .list(
          slug,
          base: branch,
          direction: 'desc',
          sort: 'created',
          state: 'open',
        )
        .toList();
  }

  /// Creates a pull request against the `baseRef` in the `slug` repository.
  ///
  /// The `entries` contains the file changes in the created pull request. This
  /// method creates a branch in the current user's forked repository to create
  /// the pull request. The current user must have a forked repository from the
  /// targeted slug, and the targeted slug must not be belong to current user.
  Future<PullRequest> createPullRequest(
    RepositorySlug slug, {
    required String title,
    String? body,
    String? commitMessage,
    required GitReference baseRef,
    List<CreateGitTreeEntry>? entries,
  }) async {
    ArgumentError.checkNotNull(slug);
    ArgumentError.checkNotNull(title);

    final RepositorySlug clientSlug = await _getCurrentUserSlug(slug.name);
    final GitTree tree = await github.git.createTree(clientSlug, CreateGitTree(entries, baseTree: baseRef.object!.sha));
    final CurrentUser currentUser = (await _getCurrentUser())!;
    final GitCommitUser commitUser = GitCommitUser(currentUser.name, currentUser.email, DateTime.now());
    final GitCommit commit = await github.git.createCommit(
      clientSlug,
      CreateGitCommit(
        commitMessage,
        tree.sha,
        parents: <String?>[baseRef.object!.sha],
        author: commitUser,
        committer: commitUser,
      ),
    );
    final GitReference headRef =
        await github.git.createReference(clientSlug, '$kRefsPrefix${_generateNewRef()}', commit.sha);
    return github.pullRequests.create(
      slug,
      CreatePullRequest(title, '${clientSlug.owner}:${headRef.ref}', baseRef.ref, body: body),
    );
  }

  /// Assigns a reviewer to the pull request in the repository.
  ///
  /// The `reviewer` contains the github login of the reviewer.
  Future<void> assignReviewer(
    RepositorySlug slug, {
    int? pullRequestNumber,
    String? reviewer,
  }) async {
    const JsonEncoder encoder = JsonEncoder();
    await github.postJSON<Map<String, dynamic>, PullRequest>(
      '/repos/${slug.fullName}/pulls/$pullRequestNumber/requested_reviewers',
      convert: (Map<String, dynamic> i) => PullRequest.fromJson(i),
      body: encoder.convert(<String, dynamic>{
        'reviewers': <String?>[reviewer],
      }),
    );
  }

  /// Retrieves issues from the repository.
  ///
  /// Uses the `labels` to return the issues that have the labels.
  ///
  /// The `state` can be set `open`, `closed, or `all`. If it is set to `open`,
  /// this method only returns issues that are currently open. If it is set to
  /// `closed`, this method returns issues that are currently closed. The `all`
  /// returns both closed and open issues. Defaults to `open`.
  Future<List<Issue>> listIssues(
    RepositorySlug slug, {
    List<String>? labels,
    String state = 'open',
  }) {
    ArgumentError.checkNotNull(slug);
    return github.issues.listByRepo(slug, labels: labels, state: state).toList();
  }

  /// Get an issue with the issue number
  Future<Issue>? getIssue(
    RepositorySlug slug, {
    required int issueNumber,
  }) {
    ArgumentError.checkNotNull(slug);
    ArgumentError.checkNotNull(issueNumber);
    return github.issues.get(slug, issueNumber);
  }

  /// Assign the issue to the assignee.
  Future<void> assignIssue(
    RepositorySlug slug, {
    required int issueNumber,
    required String assignee,
  }) async {
    ArgumentError.checkNotNull(slug);
    ArgumentError.checkNotNull(issueNumber);
    ArgumentError.checkNotNull(assignee);
    await github.issues.edit(slug, issueNumber, IssueRequest(assignee: assignee));
  }

  Future<Issue> createIssue(
    RepositorySlug slug, {
    String? title,
    String? body,
    List<String>? labels,
    String? assignee,
  }) async {
    ArgumentError.checkNotNull(slug);
    return await github.issues.create(
      slug,
      IssueRequest(title: title, body: body, labels: labels, assignee: assignee),
    );
  }

  Future<IssueComment?> createComment(
    RepositorySlug slug, {
    required int issueNumber,
    required String body,
  }) async {
    ArgumentError.checkNotNull(slug);
    ArgumentError.checkNotNull(issueNumber);
    return await github.issues.createComment(slug, issueNumber, body);
  }

  Future<List<IssueLabel>> replaceLabelsForIssue(
    RepositorySlug slug, {
    required int issueNumber,
    required List<String> labels,
  }) async {
    ArgumentError.checkNotNull(slug);
    ArgumentError.checkNotNull(issueNumber);
    final Response response = await github.request(
      'PUT',
      '/repos/${slug.fullName}/issues/$issueNumber/labels',
      body: GitHubJson.encode(labels),
    );
    final List<dynamic> body = jsonDecode(response.body) as List<dynamic>;
    return body.map((dynamic it) => IssueLabel.fromJson(it as Map<String, dynamic>)).toList();
  }

  /// Returns changed files for a [PullRequest].
  ///
  /// See more:
  ///   * https://developer.github.com/v3/pulls/#list-pull-requests-files
  Future<List<String>> listFiles(PullRequest pullRequest) async {
    final List<PullRequestFile> files =
        await github.pullRequests.listFiles(pullRequest.base!.repo!.slug(), pullRequest.number!).toList();
    log.fine('List of files: $files');
    return files.map((PullRequestFile file) {
      return file.filename!;
    }).toList();
  }

  /// Gets the file content as UTF8 string of the file specified by the `path`
  /// in the repository.
  Future<String> getFileContent(RepositorySlug slug, String path, {String? ref}) async {
    ArgumentError.checkNotNull(slug);
    ArgumentError.checkNotNull(path);
    final RepositoryContents contents = await github.repositories.getContents(slug, path, ref: ref);
    if (!contents.isFile) {
      throw 'The path $path should point to a file, but it is not!';
    }
    final String content = utf8.decode(base64.decode(contents.file!.content!.replaceAll('\n', '')));
    return content;
  }

  /// Gets the reference of a specific branch in the repository.
  Future<GitReference> getReference(RepositorySlug slug, String ref) {
    ArgumentError.checkNotNull(slug);
    ArgumentError.checkNotNull(ref);
    return github.git.getReference(slug, ref);
  }

  /// Returns JSON of the current GitHub API quota usage.
  ///
  /// This does not consume any API usage.
  ///
  /// Reference:
  ///   * https://docs.github.com/en/rest/reference/rate-limit
  Future<RateLimit> getRateLimit() => github.misc.getRateLimit();

  CurrentUser? _currentUser;

  Future<CurrentUser?> _getCurrentUser() async {
    _currentUser ??= await github.users.getCurrentUser();
    return _currentUser;
  }

  Future<RepositorySlug> _getCurrentUserSlug(String repository) async {
    return RepositorySlug((await _getCurrentUser())!.login!, repository);
  }

  String _generateNewRef() {
    const String chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
    final Random rnd = Random();
    return String.fromCharCodes(Iterable<int>.generate(10, (_) => chars.codeUnitAt(rnd.nextInt(chars.length))));
  }
}
