// Copyright 2020 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:async';
import 'dart:convert';
import 'dart:io';

import 'package:cocoon_service/src/request_handling/exceptions.dart';
import 'package:github/github.dart';
import 'package:googleapis_auth/auth_io.dart';
import 'package:http/http.dart' as http;
import 'package:http/retry.dart';
import 'package:meta/meta.dart';

import '../model/gerrit/commit.dart';
import 'logging.dart';

/// Communicates with gerrit APIs https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html
/// to get information about projects hosted in Git on Borg.
class GerritService {
  GerritService({
    http.Client? httpClient,
    @visibleForTesting this.authClientProvider = clientViaApplicationDefaultCredentials,
    @visibleForTesting this.retryDelay,
  }) : httpClient = httpClient ?? http.Client();

  final http.Client httpClient;

  final Duration? retryDelay;

  /// Provider for generating a [http.Client] that is authenticated to make calls to GCP services.
  final Future<AutoRefreshingAuthClient> Function({
    http.Client? baseClient,
    required List<String> scopes,
  }) authClientProvider;

  /// Gets the branches from a remote git repository using the gerrit APIs.
  ///
  /// [subString] allows to filter branches with this text (not case sensitive).
  ///
  /// See more:
  ///   * https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#list-branches
  Future<List<String>> branches(String repo, String project, {String? subString}) async {
    final Map<String, String> queryParameters = <String, String>{
      if (subString != null && subString.isNotEmpty) 'm': subString,
    };
    final Uri url = Uri.https(repo, 'projects/$project/branches', queryParameters);
    final List<dynamic> response = await _get(url) as List<dynamic>;

    final List<String> branches = <String>[];

    final Iterable<Map<String, dynamic>> json = response.map((dynamic e) => e as Map<String, dynamic>);
    for (Map<String, dynamic> element in json) {
      branches.add(element['ref'] as String);
    }

    return branches;
  }

  /// Gets the commit log for a project-branch pair.
  Future<Iterable<GerritCommit>> commits(RepositorySlug slug, String branch) async {
    final Uri url =
        Uri.https('${slug.owner}.googlesource.com', '${slug.name}/+log/refs/heads/$branch', <String, String>{
      'format': 'json',
    });
    final Map<String, dynamic> response = await _get(url) as Map<String, dynamic>;
    final List<dynamic> commitsJson = response['log'] as List<dynamic>;

    return commitsJson.map((dynamic part) => GerritCommit.fromJson(part as Map<String, dynamic>));
  }

  /// Creates a new branch.
  ///
  /// See more:
  ///   * https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#create-branch
  Future<void> createBranch(RepositorySlug slug, String branchName, String revision) async {
    log.info('Creating branch $branchName at $revision');
    final Uri url = Uri.https('${slug.owner}-review.googlesource.com', 'projects/${slug.name}/branches/$branchName');
    String body = jsonEncode(<String, String>{
      'revision': revision,
    });
    final Map<String, dynamic> response = await _put(
      url,
      body: body,
      branchName: branchName,
    ) as Map<String, dynamic>;
    log.info(response);
    if (response['revision'] != revision) {
      throw const InternalServerError('Failed to create branch');
    }
    log.info('Created branch $branchName');
  }

  Future<dynamic> _get(Uri url) async {
    final RetryClient client = RetryClient(httpClient);
    final http.Response response = await client.get(url);

    /// To prevent against Cross Site Script Inclusion (XSSI) attacks, the JSON response body starts with a magic prefix line that
    /// must be stripped before feeding the rest of the response body to a JSON parser. The magic prefix is ")]}'".
    final String jsonBody = response.body.replaceRange(0, 4, '');
    return jsonDecode(jsonBody) as dynamic;
  }

  Future<dynamic> _put(
    Uri url, {
    Object? body,
    // TODO(chillers): Remove once b/239021831 has been fixed by the GoB side.
    String? branchName,
  }) async {
    final http.Client authClient = await authClientProvider(baseClient: httpClient, scopes: <String>[]);
    // GoB replicas may not have all the Flutter state, and can require several retries
    final http.Client client = RetryClient(
      authClient,
      when: (http.BaseResponse response) => _responseIsAcceptable(response) == false,
      delay: (int attempt) => retryDelay ?? const Duration(seconds: 3) * attempt,
    );
    final http.Response response = await client.put(
      url,
      body: body,
      headers: <String, String>{
        // TODO(chillers): Remove once b/239021831 has been fixed by the GoB side.
        'X-Gerrit-Trace': 'bug-239021831-$branchName'
      },
    );
    if (_responseIsAcceptable(response) == false) {
      throw InternalServerError('Gerrit returned ${response.statusCode} which is not 200 or 202');
    }
    log.info('Sent PUT to $url');
    log.info(response.body);
    // Remove XSS token
    final String jsonBody = response.body.replaceRange(0, 4, '');
    log.info(jsonBody);
    return jsonDecode(jsonBody);
  }

  bool _responseIsAcceptable(http.BaseResponse response) =>
      response.statusCode == HttpStatus.ok || response.statusCode == HttpStatus.accepted;
}
