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

import 'package:cocoon_service/ci_yaml.dart';
import 'package:cocoon_service/src/request_handlers/test_ownership.dart';
import 'package:collection/collection.dart';
import 'package:github/github.dart';

import '../service/bigquery.dart';
import '../service/github_service.dart';
import '../../protos.dart' as pb;

// String constants.
const String kFlakeLabel = 'c: flake';
const String kFrameworkLabel = 'team-framework';
const String kToolLabel = 'team-tool';
const String kEngineLabel = 'team-engine';
const String kWebLabel = 'team-web';
const String kInfraLabel = 'team-infra';
const String kAndroidLabel = 'team-android';
const String kIosLabel = 'team-ios';
const String kReleaseLabel = 'team-release';
const String kEcosystemLabel = 'team-ecosystem';
const String kP0Label = 'P0';
const String kP1Label = 'P1';
const String kP2Label = 'P2';
const String kP3Label = 'P3';

const String kBigQueryProjectId = 'flutter-dashboard';
const String kCiYamlTargetsKey = 'targets';
const String kCiYamlTargetNameKey = 'name';
const String kCiYamlTargetIgnoreFlakiness = 'ignore_flakiness';
const String kCiYamlTargetIsFlakyKey = 'bringup';
const String kCiYamlPropertiesKey = 'properties';
const String kCiYamlTargetTagsKey = 'tags';
const String kCiYamlTargetTagsShard = 'shard';
const String kCiYamlTargetTagsFirebaselab = 'firebaselab';
const String kCiYamlTargetTagsDevicelab = 'devicelab';
const String kCiYamlTargetTagsFramework = 'framework';
const String kCiYamlTargetTagsHostonly = 'hostonly';

const String kMasterRefs = 'heads/master';
const String kModifyMode = '100644'; // This is equivalent to mode: `-rw-r--r--`.
const String kModifyType = 'blob';

const int kSuccessBuildNumberLimit = 3;
const int kFlayRatioBuildNumberList = 10;
const double kDefaultFlakyRatioThreshold = 0.02;
const int kGracePeriodForClosedFlake = 15; // days

const String _commitPrefix = 'https://github.com/flutter/flutter/commit/';
const String _buildDashboardPrefix = 'https://flutter-dashboard.appspot.com/#/build';
const String _prodBuildPrefix = 'https://ci.chromium.org/ui/p/flutter/builders/prod/';
const String _stagingBuildPrefix = 'https://ci.chromium.org/ui/p/flutter/builders/staging/';
const String _flakeRecordPrefix =
    'https://data.corp.google.com/sites/flutter_infra_metrics_datasite/flutter_check_test_flakiness_status_dashboard/?p=BUILDER_NAME:';

/// A builder to build a new issue for a flake.
class IssueBuilder {
  IssueBuilder({
    required this.statistic,
    required this.ownership,
    required this.threshold,
    this.bringup = false,
  });

  final BuilderStatistic statistic;
  final TestOwnership ownership;
  final double threshold;
  final bool bringup;

  Bucket get buildBucket {
    return bringup ? Bucket.staging : Bucket.prod;
  }

  String get issueTitle {
    return '${statistic.name} is ${_formatRate(statistic.flakyRate)}% flaky';
  }

  String? get issueAssignee {
    return ownership.owner;
  }

  /// Return `kSuccessBuildNumberLimit` successful builds if there are more. Otherwise return what's available.
  int numberOfSuccessBuilds(int numberOfAvailableSuccessBuilds) {
    return numberOfAvailableSuccessBuilds >= kSuccessBuildNumberLimit
        ? kSuccessBuildNumberLimit
        : numberOfAvailableSuccessBuilds;
  }

  String get issueBody {
    return '''
${_buildHiddenMetaTags(name: statistic.name)}
${_issueSummary(statistic, threshold, bringup)}

One recent flaky example for a same commit: ${_issueBuildLink(builder: statistic.name, build: statistic.flakyBuildOfRecentCommit, bucket: buildBucket)}
Commit: $_commitPrefix${statistic.recentCommit}

Flaky builds:
${_issueBuildLinks(builder: statistic.name, builds: statistic.flakyBuilds!, bucket: buildBucket)}

Recent test runs:
${_issueBuilderLink(statistic.name)}

Please follow https://github.com/flutter/flutter/wiki/Reducing-Test-Flakiness#fixing-flaky-tests to fix the flakiness and enable the test back after validating the fix (internal dashboard to validate: go/flutter_test_flakiness).
''';
  }

  List<String> get issueLabels {
    final List<String> labels = <String>[
      kFlakeLabel,
      kP0Label,
    ];
    final String? teamLabel = getTeamLabelFromTeam(ownership.team);
    if (teamLabel != null && teamLabel.isNotEmpty == true) {
      labels.add(teamLabel);
    }
    return labels;
  }
}

/// A builder to build the update comment and labels for an existing open flaky
/// issue.
class IssueUpdateBuilder {
  IssueUpdateBuilder({
    required this.statistic,
    required this.threshold,
    required this.existingIssue,
    required this.bucket,
  });

  final BuilderStatistic statistic;
  final double threshold;
  final Issue existingIssue;
  final Bucket bucket;

  bool get isBelow => statistic.flakyRate < threshold;

  String get bucketString => bucket.toString().split('.').last;

  List<String> get issueLabels {
    final List<String> existingLabels = existingIssue.labels.map<String>((IssueLabel label) => label.name).toList();
    // Update the priority.
    if (!existingLabels.contains(kP0Label) && !isBelow) {
      existingLabels.add(kP0Label);
      existingLabels.remove(kP1Label);
      existingLabels.remove(kP2Label);
      existingLabels.remove(kP3Label);
    }
    return existingLabels;
  }

  String get issueUpdateComment {
    String result =
        '[$bucketString pool] flaky ratio for the past (up to) 100 commits between ${statistic.fromDate} and ${statistic.toDate} is ${_formatRate(statistic.flakyRate)}%. Flaky number: ${statistic.flakyNumber}; total number: ${statistic.totalNumber}.\n';
    if (statistic.flakyRate > 0.0) {
      result += '''
One recent flaky example for a same commit: ${_issueBuildLink(builder: statistic.name, build: statistic.flakyBuildOfRecentCommit, bucket: bucket)}
Commit: $_commitPrefix${statistic.recentCommit}
Flaky builds:
${_issueBuildLinks(builder: statistic.name, builds: statistic.flakyBuilds!, bucket: bucket)}

Recent test runs:
${_issueBuilderLink(statistic.name)}
''';
    }
    return result;
  }
}

/// A builder to build the pull request title and body for marking test flaky
class PullRequestBuilder {
  PullRequestBuilder({
    required this.statistic,
    required this.ownership,
    required this.issue,
  });

  final BuilderStatistic statistic;
  final TestOwnership ownership;
  final Issue issue;

  String get pullRequestTitle => 'Marks ${statistic.name} to be flaky';
  String get pullRequestBody => '${_buildHiddenMetaTags(name: statistic.name)}Issue link: ${issue.htmlUrl}\n';
  String? get pullRequestReviewer => ownership.owner;
}

/// A builder to build the pull request title and body for marking test unflaky
class DeflakePullRequestBuilder {
  DeflakePullRequestBuilder({
    required this.name,
    required this.recordNumber,
    required this.ownership,
    this.issue,
  });

  final String? name;
  final Issue? issue;
  final TestOwnership ownership;
  final int recordNumber;

  String get pullRequestTitle => 'Marks $name to be unflaky';
  String get pullRequestBody {
    String body = _buildHiddenMetaTags(name: name);
    if (issue != null) {
      body +=
          'The issue ${issue!.htmlUrl} has been closed, and the test has been passing for [$recordNumber consecutive runs](${Uri.encodeFull('$_flakeRecordPrefix"$name"')}).\n';
    } else {
      body +=
          'The test has been passing for [$recordNumber consecutive runs](${Uri.encodeFull('$_flakeRecordPrefix"$name"')}).\n';
    }
    body += 'This test can be marked as unflaky.\n';
    return body;
  }

  String? get pullRequestReviewer => ownership.owner;
}

// TESTOWNER Regex

const String kOwnerGroupName = 'owners';
final RegExp devicelabTestOwners =
    RegExp('## Linux Android DeviceLab tests\n(?<$kOwnerGroupName>.+)## Host only framework tests', dotAll: true);
final RegExp frameworkHostOnlyTestOwners =
    RegExp('## Host only framework tests\n(?<$kOwnerGroupName>.+)## Firebase tests', dotAll: true);
final RegExp firebaselabTestOwners = RegExp('## Firebase tests\n(?<$kOwnerGroupName>.+)## Shards tests', dotAll: true);
final RegExp shardTestOwners = RegExp('## Shards tests\n(?<$kOwnerGroupName>.+)', dotAll: true);

// Utils methods

/// Gets the existing flaky issues.
///
/// The state can be 'open', 'closed', or 'all'.
Future<Map<String?, Issue>> getExistingIssues(GithubService gitHub, RepositorySlug slug, {String state = 'all'}) async {
  final Map<String?, Issue> nameToExistingIssue = <String?, Issue>{};
  for (final Issue issue in await gitHub.listIssues(slug, state: state, labels: <String>[kFlakeLabel])) {
    if (issue.htmlUrl.contains('pull') == true) {
      // For some reason, this github api may also return pull requests.
      continue;
    }
    final Map<String, dynamic>? metaTags = retrieveMetaTagsFromContent(issue.body);
    if (metaTags != null) {
      final String? name = metaTags['name'] as String?;
      if (!nameToExistingIssue.containsKey(name) || _isOtherIssueMoreImportant(nameToExistingIssue[name]!, issue)) {
        nameToExistingIssue[name] = issue;
      }
    }
  }
  return nameToExistingIssue;
}

/// Gets the existing open pull requests that make tests flaky.
Future<Map<String?, PullRequest>> getExistingPRs(GithubService gitHub, RepositorySlug slug) async {
  final Map<String?, PullRequest> nameToExistingPRs = <String?, PullRequest>{};
  for (final PullRequest pr in await gitHub.listPullRequests(slug, null)) {
    try {
      if (pr.body == null) {
        continue;
      }
      final Map<String, dynamic>? metaTags = retrieveMetaTagsFromContent(pr.body!);
      if (metaTags != null) {
        nameToExistingPRs[metaTags['name'] as String] = pr;
      }
    } catch (e) {
      throw 'Unable to parse body of ${pr.htmlUrl}\n$e';
    }
  }
  return nameToExistingPRs;
}

/// File a GitHub flaky issue based on builder details in recent prod/staging runs.
Future<Issue> fileFlakyIssue({
  required BuilderDetail builderDetail,
  required GithubService gitHub,
  required RepositorySlug slug,
  double threshold = kDefaultFlakyRatioThreshold,
  bool bringup = false,
}) async {
  final IssueBuilder issueBuilder = IssueBuilder(
    statistic: builderDetail.statistic,
    ownership: builderDetail.ownership,
    threshold: kDefaultFlakyRatioThreshold,
    bringup: bringup,
  );
  return gitHub.createIssue(
    slug,
    title: issueBuilder.issueTitle,
    body: issueBuilder.issueBody,
    labels: issueBuilder.issueLabels,
    assignee: issueBuilder.issueAssignee,
  );
}

/// Looks up the owner of a builder in TESTOWNERS file.
TestOwnership getTestOwnership(pb.Target target, BuilderType type, String testOwnersContent) {
  final TestOwner testOwner = TestOwner(type);
  return testOwner.getTestOwnership(target, testOwnersContent);
}

/// Gets the [BuilderType] of the builder by looking up the information in the
/// ci.yaml.
BuilderType getTypeForBuilder(String? targetName, CiYaml ciYaml, {bool unfilteredTargets = false}) {
  final List<String>? tags = _getTags(targetName, ciYaml, unfilteredTargets: unfilteredTargets);
  if (tags == null || tags.isEmpty) {
    return BuilderType.unknown;
  }

  bool hasFrameworkTag = false;
  bool hasHostOnlyTag = false;
  // If tags contain 'shard', it must be a shard test.
  // If tags contain 'devicelab', it must be a devicelab test.
  // If tags contain 'firebaselab`, it must be a firebase tests.
  // Otherwise, it is framework host only test if its tags contain both
  // 'framework' and 'hostonly'.
  for (String tag in tags) {
    if (tag == kCiYamlTargetTagsFirebaselab) {
      return BuilderType.firebaselab;
    } else if (tag == kCiYamlTargetTagsShard) {
      return BuilderType.shard;
    } else if (tag == kCiYamlTargetTagsDevicelab) {
      return BuilderType.devicelab;
    } else if (tag == kCiYamlTargetTagsFramework) {
      hasFrameworkTag = true;
    } else if (tag == kCiYamlTargetTagsHostonly) {
      hasHostOnlyTag = true;
    }
  }
  return hasFrameworkTag && hasHostOnlyTag ? BuilderType.frameworkHostOnly : BuilderType.unknown;
}

List<String>? _getTags(String? targetName, CiYaml ciYaml, {bool unfilteredTargets = false}) {
  final Set<Target> allUniqueTargets = {};
  if (!unfilteredTargets) {
    allUniqueTargets.addAll(ciYaml.presubmitTargets);
    allUniqueTargets.addAll(ciYaml.postsubmitTargets);
  } else {
    allUniqueTargets.addAll(ciYaml.targets);
  }

  final Target? target = allUniqueTargets.firstWhereOrNull((element) => element.value.name == targetName);
  return target?.tags;
}

bool _isOtherIssueMoreImportant(Issue original, Issue other) {
  // Open issues are always more important than closed issues. If both issue
  // are closed, the one that is most recently created is more important.
  if (original.isOpen && other.isOpen) {
    throw 'There should not be two open issues for the same test';
  } else if (original.isOpen && other.isClosed) {
    return false;
  } else if (original.isClosed && other.isOpen) {
    return true;
  } else {
    return other.createdAt!.isAfter(original.createdAt!);
  }
}

String _buildHiddenMetaTags({String? name}) {
  return '''<!-- meta-tags: To be used by the automation script only, DO NOT MODIFY.
{
  "name": "$name"
}
-->
''';
}

final RegExp _issueHiddenMetaTagsRegex =
    RegExp(r'<!-- meta-tags: To be used by the automation script only, DO NOT MODIFY\.(?<meta>.+)-->', dotAll: true);

/// Checks whether the github content contains meta tags and returns the meta
/// tags if it does.
///
/// The script generated contents for issue bodies or pull request bodies
/// contain the meta tags. Using this method is a reliable way to check whether
/// a issue or pull request is generated by this script.
Map<String, dynamic>? retrieveMetaTagsFromContent(String content) {
  final RegExpMatch? match = _issueHiddenMetaTagsRegex.firstMatch(content);
  if (match == null) {
    return null;
  }
  return jsonDecode(match.namedGroup('meta')!) as Map<String, dynamic>?;
}

String _formatRate(double rate) => (rate * 100).toStringAsFixed(2);

String _issueBuildLinks({String? builder, required List<String> builds, Bucket bucket = Bucket.prod}) {
  return builds.map((String build) => _issueBuildLink(builder: builder, build: build, bucket: bucket)).join('\n');
}

String _issueSummary(BuilderStatistic statistic, double threshold, bool bringup) {
  final String summary;
  if (bringup) {
    summary =
        'The post-submit test builder `${statistic.name}`, which has been marked `bringup: true`, had ${statistic.flakyNumber} flakes over past ${statistic.totalNumber} commits.';
  } else {
    summary =
        'The post-submit test builder `${statistic.name}` had a flaky ratio ${_formatRate(statistic.flakyRate)}% for the past (up to) 100 commits, which is above our ${_formatRate(threshold)}% threshold.';
  }
  return summary;
}

String _issueBuildLink({String? builder, String? build, Bucket bucket = Bucket.prod}) {
  final String buildPrefix = bucket == Bucket.staging ? _stagingBuildPrefix : _prodBuildPrefix;
  return Uri.encodeFull('$buildPrefix$builder/$build');
}

String _issueBuilderLink(String? builder) {
  return Uri.encodeFull('$_buildDashboardPrefix?taskFilter=$builder');
}

String? getTeamLabelFromTeam(Team? team) {
  return switch (team) {
    Team.framework => kFrameworkLabel,
    Team.engine => kEngineLabel,
    Team.tool => kToolLabel,
    Team.web => kWebLabel,
    Team.infra => kInfraLabel,
    Team.android => kAndroidLabel,
    Team.ios => kIosLabel,
    Team.release => kReleaseLabel,
    Team.plugins => kEcosystemLabel,
    Team.unknown || null => null,
  };
}

enum BuilderType {
  devicelab,
  frameworkHostOnly,
  shard,
  firebaselab,
  unknown,
}

enum Bucket {
  prod,
  staging,
}

enum Team {
  framework,
  engine,
  tool,
  web,
  infra,
  android,
  ios,
  release,
  plugins,
  unknown,
}

class TestOwnership {
  TestOwnership(
    this.owner,
    this.team,
  );
  String? owner;
  Team? team;
}

class BuilderDetail {
  const BuilderDetail({
    required this.statistic,
    required this.existingIssue,
    required this.existingPullRequest,
    required this.isMarkedFlaky,
    required this.ownership,
    required this.type,
  });
  final BuilderStatistic statistic;
  final Issue? existingIssue;
  final PullRequest? existingPullRequest;
  final TestOwnership ownership;
  final bool isMarkedFlaky;
  final BuilderType type;
}
