// 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:fixnum/fixnum.dart';
import 'package:flutter/foundation.dart' show compute, kIsWeb, visibleForTesting;
import 'package:flutter_dashboard/model/branch.pb.dart';
import 'package:http/http.dart' as http;

import '../logic/qualified_task.dart';
import '../model/build_status_response.pb.dart';
import '../model/commit.pb.dart';
import '../model/commit_status.pb.dart';
import '../model/key.pb.dart';
import '../model/task.pb.dart';
import 'cocoon.dart';

/// CocoonService for interacting with flutter/flutter production build data.
///
/// This queries API endpoints that are hosted on AppEngine.
class AppEngineCocoonService implements CocoonService {
  /// Creates a new [AppEngineCocoonService].
  ///
  /// If a [client] is not specified, a new [http.Client] instance is created.
  AppEngineCocoonService({http.Client? client}) : _client = client ?? http.Client();

  /// Branch on flutter/flutter to default requests for.
  final String _defaultBranch = 'master';

  /// The Cocoon API endpoint to query
  ///
  /// This is the base for all API requests to cocoon
  static const String _baseApiUrl = 'flutter-dashboard.appspot.com';

  final http.Client _client;

  @override
  Future<CocoonResponse<List<CommitStatus>>> fetchCommitStatuses({
    CommitStatus? lastCommitStatus,
    String? branch,
    required String repo,
  }) async {
    final Map<String, String?> queryParameters = <String, String?>{
      if (lastCommitStatus != null) 'lastCommitKey': lastCommitStatus.commit.key.child.name,
      'branch': branch ?? _defaultBranch,
      'repo': repo,
    };
    final Uri getStatusUrl = apiEndpoint('/api/public/get-status', queryParameters: queryParameters);

    /// This endpoint returns JSON [List<Agent>, List<CommitStatus>]
    final http.Response response = await _client.get(getStatusUrl);

    if (response.statusCode != HttpStatus.ok) {
      return CocoonResponse<List<CommitStatus>>.error('/api/public/get-status returned ${response.statusCode}');
    }

    try {
      final Map<String, dynamic> jsonResponse = jsonDecode(response.body);
      return CocoonResponse<List<CommitStatus>>.data(
        await compute<List<dynamic>, List<CommitStatus>>(_commitStatusesFromJson, jsonResponse['Statuses']),
      );
    } catch (error) {
      return CocoonResponse<List<CommitStatus>>.error(error.toString());
    }
  }

  @override
  Future<CocoonResponse<List<String>>> fetchRepos() async {
    final Uri getReposUrl = apiEndpoint('/api/public/repos');

    // This endpoint returns a JSON array of strings.1
    final http.Response response = await _client.get(getReposUrl);

    if (response.statusCode != HttpStatus.ok) {
      return CocoonResponse<List<String>>.error('$getReposUrl returned ${response.statusCode}');
    }

    List<String> repos;
    try {
      repos = List<String>.from(jsonDecode(response.body) as List<dynamic>);
    } on FormatException {
      return CocoonResponse<List<String>>.error('$getReposUrl had a malformed response');
    }
    return CocoonResponse<List<String>>.data(repos);
  }

  @override
  Future<CocoonResponse<BuildStatusResponse>> fetchTreeBuildStatus({
    String? branch,
    required String repo,
  }) async {
    final Map<String, String?> queryParameters = <String, String?>{
      'branch': branch ?? _defaultBranch,
      'repo': repo,
    };
    final Uri getBuildStatusUrl = apiEndpoint('/api/public/build-status', queryParameters: queryParameters);

    /// This endpoint returns JSON {AnticipatedBuildStatus: [BuildStatus]}
    final http.Response response = await _client.get(getBuildStatusUrl);

    if (response.statusCode != HttpStatus.ok) {
      return CocoonResponse<BuildStatusResponse>.error('/api/public/build-status returned ${response.statusCode}');
    }

    BuildStatusResponse protoResponse;
    try {
      protoResponse = BuildStatusResponse.fromJson(response.body);
    } on FormatException {
      return const CocoonResponse<BuildStatusResponse>.error('/api/public/build-status had a malformed response');
    }
    return CocoonResponse<BuildStatusResponse>.data(protoResponse);
  }

  @override
  Future<CocoonResponse<List<Branch>>> fetchFlutterBranches() async {
    final Uri getBranchesUrl = apiEndpoint('/api/public/get-branches');

    /// This endpoint returns JSON {"Branches": List<String>}
    final http.Response response = await _client.get(getBranchesUrl);

    if (response.statusCode != HttpStatus.ok) {
      return CocoonResponse<List<Branch>>.error('/api/public/get-branches returned ${response.statusCode}');
    }

    try {
      final List<dynamic> jsonResponse = jsonDecode(response.body);

      final List<Branch> branches = <Branch>[];
      for (final Map<String, dynamic> jsonBranch in jsonResponse) {
        final Map<String, dynamic> branchInfo = jsonBranch['branch'];
        branches.add(
          Branch()
            ..branch = branchInfo['branch']
            ..repository = branchInfo['repository'].split('/')[1],
        );
      }
      return CocoonResponse<List<Branch>>.data(branches);
    } catch (error) {
      return CocoonResponse<List<Branch>>.error(error.toString());
    }
  }

  @override
  Future<bool> vacuumGitHubCommits(String idToken) async {
    final Uri refreshGitHubCommitsUrl = apiEndpoint('/api/vacuum-github-commits');
    final http.Response response = await _client.get(
      refreshGitHubCommitsUrl,
      headers: <String, String>{
        'X-Flutter-IdToken': idToken,
      },
    );
    return response.statusCode == HttpStatus.ok;
  }

  @override
  Future<CocoonResponse<bool>> rerunTask(Task task, String? idToken, String repo) async {
    if (idToken == null || idToken.isEmpty) {
      return const CocoonResponse<bool>.error('Sign in to trigger reruns');
    }

    final QualifiedTask qualifiedTask = QualifiedTask.fromTask(task);
    assert(qualifiedTask.isLuci);

    /// This endpoint only returns a status code.
    final Uri postResetTaskUrl = apiEndpoint('/api/reset-prod-task');
    final http.Response response = await _client.post(
      postResetTaskUrl,
      headers: <String, String>{
        'X-Flutter-IdToken': idToken,
      },
      body: jsonEncode(<String, String>{
        'Key': task.key.child.name,
        'Repo': repo,
      }),
    );

    if (response.statusCode == HttpStatus.ok) {
      return const CocoonResponse<bool>.data(true);
    }

    return CocoonResponse<bool>.error('HTTP Code: ${response.statusCode}, ${response.body}');
  }

  /// Construct the API endpoint based on the priority of using a local endpoint
  /// before falling back to the production endpoint.
  ///
  /// This functions resolves the relative url endpoint to the production endpoint
  /// that can be used on web to the production endpoint if running not on web.
  /// This is because only on web a Cocoon backend can be running from the same
  /// host as this Flutter application, but on mobile we need to ping a separate
  /// production endpoint.
  ///
  /// The urlSuffix begins with a slash, e.g. "/api/public/get-status".
  ///
  /// [queryParameters] are appended to the url and are url encoded.
  @visibleForTesting
  Uri apiEndpoint(
    String urlSuffix, {
    Map<String, String?>? queryParameters,
  }) {
    if (kIsWeb) {
      return Uri.base.replace(path: urlSuffix, queryParameters: queryParameters);
    }
    return Uri.https(_baseApiUrl, urlSuffix, queryParameters);
  }

  List<CommitStatus> _commitStatusesFromJson(List<dynamic>? jsonCommitStatuses) {
    assert(jsonCommitStatuses != null);
    // TODO(chillers): Remove adapter code to just use proto fromJson method. https://github.com/flutter/cocoon/issues/441

    final List<CommitStatus> statuses = <CommitStatus>[];

    for (final Map<String, dynamic> jsonCommitStatus in jsonCommitStatuses!) {
      final Map<String, dynamic> checklist = jsonCommitStatus['Checklist'];
      statuses.add(
        CommitStatus()
          ..commit = _commitFromJson(checklist)
          ..branch = _branchFromJson(checklist)!
          ..tasks.addAll(_tasksFromStagesJson(jsonCommitStatus['Stages'])),
      );
    }

    return statuses;
  }

  String? _branchFromJson(Map<String, dynamic> jsonChecklist) {
    final Map<String, dynamic> checklist = jsonChecklist['Checklist'];
    return checklist['Branch'] as String?;
  }

  Commit _commitFromJson(Map<String, dynamic> jsonChecklist) {
    final Map<String, dynamic> checklist = jsonChecklist['Checklist'];

    final Map<String, dynamic> commit = checklist['Commit'];
    final Map<String, dynamic> author = commit['Author'];

    final Commit result = Commit()
      ..key = (RootKey()..child = (Key()..name = jsonChecklist['Key'] as String))
      ..timestamp = Int64() + checklist['CreateTimestamp']!
      ..sha = commit['Sha'] as String
      ..author = author['Login'] as String
      ..authorAvatarUrl = author['avatar_url'] as String
      ..repository = checklist['FlutterRepositoryPath'] as String
      ..branch = checklist['Branch'] as String;
    if (commit['Message'] != null) {
      result.message = commit['Message'] as String;
    }
    return result;
  }

  List<Task> _tasksFromStagesJson(List<dynamic> json) {
    final List<Task> tasks = <Task>[];

    for (final Map<String, dynamic> jsonStage in json) {
      tasks.addAll(_tasksFromJson(jsonStage['Tasks']));
    }

    return tasks;
  }

  List<Task> _tasksFromJson(List<dynamic> json) {
    final List<Task> tasks = <Task>[];

    for (final Map<String, dynamic> jsonTask in json) {
      //as Iterable<Map<String, Object>>
      tasks.add(_taskFromJson(jsonTask));
    }

    return tasks;
  }

  Task _taskFromJson(Map<String, dynamic> json) {
    final Map<String, dynamic> taskData = json['Task'];
    final List<dynamic>? objectRequiredCapabilities = taskData['RequiredCapabilities'] as List<dynamic>?;

    final Task task = Task()
      ..key = (RootKey()..child = (Key()..name = json['Key'] as String))
      ..createTimestamp = Int64(taskData['CreateTimestamp'] as int)
      ..startTimestamp = Int64(taskData['StartTimestamp'] as int)
      ..endTimestamp = Int64(taskData['EndTimestamp'] as int)
      ..name = taskData['Name'] as String
      ..attempts = taskData['Attempts'] as int
      ..isFlaky = taskData['Flaky'] as bool
      ..timeoutInMinutes = taskData['TimeoutInMinutes'] as int
      ..reason = taskData['Reason'] as String
      ..requiredCapabilities.add(objectRequiredCapabilities.toString())
      ..reservedForAgentId = taskData['ReservedForAgentID'] as String
      ..stageName = taskData['StageName'] as String
      ..status = taskData['Status'] as String
      ..isTestFlaky = taskData['TestFlaky'] as bool? ?? false;

    if (taskData['StageName'] != StageName.cirrus) {
      task
        ..buildNumberList = taskData['BuildNumberList'] as String? ?? ''
        ..builderName = taskData['BuilderName'] as String? ?? ''
        ..luciBucket = taskData['LuciBucket'] as String? ?? '';
    }
    return task;
  }
}
