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

import 'package:googleapis_auth/auth_io.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';

import 'package:buildbucket/buildbucket_pb.dart' as bbv2;
import 'access_token_provider.dart';

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

// TODO generalize the two clients to remove this.
/// A client interface to LUCI BuildBucket
@immutable
class BuildBucketV2Client {
  /// Creates a new build bucket Client.
  ///
  /// The [buildBucketUri] parameter must not be null, and will be defaulted to
  /// [kDefaultBuildBucketUri] if not specified.
  ///
  /// The [httpClient] parameter will be defaulted to `HttpClient()` if not
  /// specified or null.
  BuildBucketV2Client({
    this.buildBucketBuilderUri = kDefaultBuildBucketBuilderUri,
    this.buildBucketBuildUri = kDefaultBuildBucketBuildUri,
    this.accessTokenService,
    http.Client? httpClient,
  }) : httpClient = httpClient ?? http.Client();

  /// Garbage to prevent browser/JSON parsing exploits.
  static const String kRpcResponseGarbage = ")]}'";

  /// The default endpoint for BuildBucket build requests.
  static const String kDefaultBuildBucketBuildUri = 'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builds';

  /// The default endpoint for BuildBucket builder requests.
  static const String kDefaultBuildBucketBuilderUri = 'https://cr-buildbucket.appspot.com/prpc/buildbucket.v2.Builders';

  /// The base URI for build bucket requests.
  ///
  /// Defaults to [kDefaultBuildBucketBuildUri].
  final String buildBucketBuildUri;

  /// The base URI for build bucket requests.
  ///
  /// Defaults to [kDefaultBuildBucketBuilderUri].
  final String buildBucketBuilderUri;

  /// The token provider for OAuth2 requests.
  ///
  /// If this is non-null, an access token will be attached to any outbound
  /// HTTP requests issued by this client.
  final AccessTokenService? accessTokenService;

  /// The [http.Client] to use for requests.
  final http.Client httpClient;

  Future<String> _postRequest(
    String path,
    String request, {
    String buildBucketUri = kDefaultBuildBucketBuildUri,
  }) async {
    final Uri url = Uri.parse('$buildBucketUri$path');
    final AccessToken? token = await accessTokenService?.createAccessToken();

    log.info('Making bbv2 request with path: $url and body: $request');

    final http.Response response = await httpClient.post(
      url,
      body: request,
      headers: <String, String>{
        HttpHeaders.contentTypeHeader: 'application/json',
        HttpHeaders.acceptHeader: 'application/json',
        if (token != null) HttpHeaders.authorizationHeader: '${token.type} ${token.data}',
      },
    );

    log.info('bbv2 request returned response code ${response.statusCode}');
    log.info('bbv2 request response body: ${response.body}');

    if (response.statusCode < 300) {
      return response.body.substring(kRpcResponseGarbage.length);
    }
    throw BuildBucketException(response.statusCode, response.body);
  }

  /// The RPC request to schedule a build.
  Future<bbv2.Build> scheduleBuild(
    bbv2.ScheduleBuildRequest request, {
    String buildBucketUri = kDefaultBuildBucketBuildUri,
  }) async {
    final bbv2.Build build = bbv2.Build.create();

    final String responseBody = await _postRequest(
      '/ScheduleBuild',
      jsonEncode(request.toProto3Json()),
      buildBucketUri: buildBucketUri,
    );

    build.mergeFromProto3Json(jsonDecode(responseBody));
    return build;
  }

  /// The RPC request to search for builds.
  Future<bbv2.SearchBuildsResponse> searchBuilds(
    bbv2.SearchBuildsRequest request, {
    String buildBucketUri = kDefaultBuildBucketBuildUri,
  }) async {
    final bbv2.SearchBuildsResponse searchBuildsResponse = bbv2.SearchBuildsResponse.create();

    final String responseBody = await _postRequest(
      '/SearchBuilds',
      jsonEncode(request.toProto3Json()),
      buildBucketUri: buildBucketUri,
    );

    searchBuildsResponse.mergeFromProto3Json(jsonDecode(responseBody));
    return searchBuildsResponse;
  }

  /// The RPC method to batch multiple RPC methods in a single HTTP request.
  ///
  /// The response is guaranteed to contain line-item responses for all
  /// line-item requests that were issued in [request]. If only a subset of
  /// responses were retrieved, a [BatchRequestException] will be thrown.
  Future<bbv2.BatchResponse> batch(
    bbv2.BatchRequest request, {
    String buildBucketUri = kDefaultBuildBucketBuildUri,
  }) async {
    final bbv2.BatchResponse response = bbv2.BatchResponse.create();
    final String responseBody = await _postRequest(
      '/Batch',
      //For some reason this needs to be stringified as the proto message is not quoted for some reason.
      jsonEncode(request.toProto3Json()),
      // this needs to use an object with mergeFromProto3Json, cannot use fromJson here.
      buildBucketUri: buildBucketUri,
    );
    response.mergeFromProto3Json(jsonDecode(responseBody));
    if (response.responses.length != request.requests.length) {
      throw BatchRequestException('Failed to execute all requests');
    }
    log.info('Batch response matches request size.');
    return response;
  }

  /// The RPC request to cancel a build.
  Future<bbv2.Build> cancelBuild(
    bbv2.CancelBuildRequest request, {
    String buildBucketUri = kDefaultBuildBucketBuildUri,
  }) async {
    final bbv2.Build build = bbv2.Build.create();

    final String responseBody = await _postRequest(
      '/CancelBuild',
      jsonEncode(request.toProto3Json()),
      buildBucketUri: buildBucketUri,
    );

    build.mergeFromProto3Json(jsonDecode(responseBody));
    return build;
  }

  /// The RPC request to get details about a build.
  Future<bbv2.Build> getBuild(
    bbv2.GetBuildRequest request, {
    String buildBucketUri = kDefaultBuildBucketBuildUri,
  }) async {
    final bbv2.Build build = bbv2.Build.create();

    final String responseBody = await _postRequest(
      '/GetBuild',
      jsonEncode(request.toProto3Json()),
      buildBucketUri: buildBucketUri,
    );

    build.mergeFromProto3Json(jsonDecode(responseBody));
    return build;
  }

  /// The RPC request to get a list of builders.
  Future<bbv2.ListBuildersResponse> listBuilders(
    bbv2.ListBuildersRequest request, {
    String buildBucketUri = kDefaultBuildBucketBuilderUri,
  }) async {
    final bbv2.ListBuildersResponse listBuildersResponse = bbv2.ListBuildersResponse.create();

    final String responseBody = await _postRequest(
      '/ListBuilders',
      jsonEncode(request.toProto3Json()),
      buildBucketUri: buildBucketUri,
    );

    listBuildersResponse.mergeFromProto3Json(jsonDecode(responseBody));
    return listBuildersResponse;
  }

  /// Closes the underlying [HttpClient].
  ///
  /// Once this call completes, additional RPC requests will throw an exception.
  void close() {
    httpClient.close();
  }
}

class BuildBucketException implements Exception {
  const BuildBucketException(this.statusCode, this.message);

  /// The HTTP status code of the error.
  final int statusCode;

  /// The message from the server.
  final String message;

  @override
  String toString() => '$runtimeType: [$statusCode]: $message';
}

class BatchRequestException implements Exception {
  BatchRequestException(this.message);

  final String message;

  @override
  String toString() => message;
}
