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

import 'package:github/github.dart' as github;
import 'package:github/hooks.dart';

import '../foundation/github_checks_util.dart';
import '../model/luci/buildbucket.dart';
import '../model/luci/push_message.dart' as push_message;
import 'config.dart';
import 'logging.dart';
import 'luci_build_service.dart';
import 'scheduler.dart';

const String kGithubSummary = '''
**[Understanding a LUCI build failure](https://github.com/flutter/flutter/wiki/Understanding-a-LUCI-build-failure)**

''';

/// Controls triggering builds and updating their status in the Github UI.
class GithubChecksService {
  GithubChecksService(this.config, {GithubChecksUtil? githubChecksUtil})
      : githubChecksUtil = githubChecksUtil ?? const GithubChecksUtil();

  Config config;
  GithubChecksUtil githubChecksUtil;

  static Set<github.CheckRunConclusion> failedStatesSet = <github.CheckRunConclusion>{
    github.CheckRunConclusion.cancelled,
    github.CheckRunConclusion.failure,
  };

  /// Takes a [CheckSuiteEvent] and trigger all the relevant builds if this is a
  /// new commit or only failed builds if the event was generated by a click on
  /// the re-run all button in the Github UI.
  /// Relevant API docs:
  ///   https://docs.github.com/en/rest/reference/checks#create-a-check-suite
  ///   https://docs.github.com/en/rest/reference/checks#rerequest-a-check-suite
  Future<void> handleCheckSuite(
    github.PullRequest pullRequest,
    CheckSuiteEvent checkSuiteEvent,
    Scheduler scheduler,
  ) async {
    switch (checkSuiteEvent.action) {
      case 'requested':
        // Trigger all try builders.
        await scheduler.triggerPresubmitTargets(
          pullRequest: pullRequest,
        );
        break;

      case 'rerequested':
        pullRequest.head = github.PullRequestHead(sha: checkSuiteEvent.checkSuite?.headSha);
        return await scheduler.retryPresubmitTargets(
          pullRequest: pullRequest,
          checkSuiteEvent: checkSuiteEvent,
        );
    }
  }

  /// Updates the Github build status using a [BuildPushMessage] sent by LUCI in
  /// a pub/sub notification.
  /// Relevant APIs:
  ///   https://docs.github.com/en/rest/reference/checks#update-a-check-run
  Future<bool> updateCheckStatus(
    push_message.BuildPushMessage buildPushMessage,
    LuciBuildService luciBuildService,
    github.RepositorySlug slug,
  ) async {
    final push_message.Build? build = buildPushMessage.build;
    if (buildPushMessage.userData!.isEmpty) {
      return false;
    }
    Map<String, dynamic> userData;
    try {
      userData = jsonDecode(buildPushMessage.userData!) as Map<String, dynamic>;
    } on FormatException {
      userData = jsonDecode(String.fromCharCodes(base64Decode(buildPushMessage.userData!))) as Map<String, dynamic>;
    }

    if (!userData.containsKey('check_run_id') ||
        !userData.containsKey('repo_owner') ||
        !userData.containsKey('repo_name')) {
      log.severe(
        'UserData did not contain check_run_id,'
        'repo_owner, or repo_name: $userData',
      );
      return false;
    }
    final github.CheckRun checkRun = await githubChecksUtil.getCheckRun(
      config,
      slug,
      userData['check_run_id'] as int?,
    );
    final github.CheckRunStatus status = statusForResult(build!.status);
    final github.CheckRunConclusion? conclusion =
        (buildPushMessage.build!.result != null) ? conclusionForResult(buildPushMessage.build!.result) : null;
    // Do not override url for completed status.
    final String? url = status == github.CheckRunStatus.completed ? checkRun.detailsUrl : buildPushMessage.build!.url;
    github.CheckRunOutput? output;
    // If status has completed with failure then provide more details.
    if (status == github.CheckRunStatus.completed && failedStatesSet.contains(conclusion)) {
      final Build build =
          await luciBuildService.getBuildById(buildPushMessage.build!.id, fields: 'id,builder,summaryMarkdown');
      output = github.CheckRunOutput(title: checkRun.name!, summary: getGithubSummary(build.summaryMarkdown));
    }
    log.fine('Updating check run with output: [$output]');
    await githubChecksUtil.updateCheckRun(
      config,
      slug,
      checkRun,
      status: status,
      conclusion: conclusion,
      detailsUrl: url,
      output: output,
    );
    return true;
  }

  /// Appends triage wiki page to `summaryMarkdown` from LUCI build so that people can easily
  /// reference from github check run page.
  String getGithubSummary(String? summary) {
    if (summary == null) {
      return '${kGithubSummary}Empty summaryMarkdown';
    }
    // This is an imposed GitHub limit
    const int checkSummaryLimit = 65535;
    // This is to give buffer room incase GitHub lowers the amount.
    const int checkSummaryBufferLimit = checkSummaryLimit - 10000 - kGithubSummary.length;
    // Return the last [checkSummaryBufferLimit] characters as they are likely the most relevant.
    if (summary.length > checkSummaryBufferLimit) {
      final String truncatedSummary = summary.substring(summary.length - checkSummaryBufferLimit);
      summary = '[TRUNCATED...] $truncatedSummary';
    }
    return '$kGithubSummary$summary';
  }

  /// Transforms a [push_message.Result] to a [github.CheckRunConclusion].
  /// Relevant APIs:
  ///   https://developer.github.com/v3/checks/runs/#check-runs
  github.CheckRunConclusion conclusionForResult(push_message.Result? result) {
    switch (result) {
      case push_message.Result.canceled:
        // Set conclusion cancelled as a failure to ensure developers can retry
        // tasks when builds timeout.
        return github.CheckRunConclusion.failure;
      case push_message.Result.failure:
      case push_message.Result.infraFailure:
        return github.CheckRunConclusion.failure;
      case push_message.Result.success:
        return github.CheckRunConclusion.success;
      case null:
        throw StateError('unreachable');
    }
  }

  /// Transforms a [push_message.Status] to a [github.CheckRunStatus].
  /// Relevant APIs:
  ///   https://developer.github.com/v3/checks/runs/#check-runs
  github.CheckRunStatus statusForResult(push_message.Status? status) {
    switch (status) {
      case push_message.Status.completed:
        return github.CheckRunStatus.completed;
      case push_message.Status.scheduled:
        return github.CheckRunStatus.queued;
      case push_message.Status.started:
        return github.CheckRunStatus.inProgress;
      case null:
        throw StateError('unreachable');
    }
  }
}
