// Copyright 2023 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 'dart:math' as math;

import 'package:github/github.dart';
import 'package:http/http.dart';

import 'cache.dart';
import 'utils.dart';

const List<String> priorities = <String>['P0', 'P1', 'P2', 'P3'];

class FullIssue {
  FullIssue(
    this.repo,
    this.issueNumber,
    this._metadata,
    this.comments,
    this.reactions, {
    this.redirect,
    this.isDeleted = false,
  }) {
    _labels = _metadata?.labels
        .map<String>((final IssueLabel label) => label.name)
        .toSet();
    if (_labels != null) {
      final matches = priorities.toSet().intersection(_labels);
      if (matches.length > 1) {
        print(
          '\nWARNING: Too many priority labels on issue #$issueNumber: ${matches.join(', ')}',
        );
        for (final priority in priorities) {
          if (matches.contains(priority)) {
            _priority = priority;
            break;
          }
        }
      } else if (matches.length == 1) {
        _priority = matches.single;
      } else {
        _priority = null;
      }
    }
  }

  final RepositorySlug repo;
  final int issueNumber;
  final Issue? _metadata;
  Issue get metadata => _metadata!; // only available when isValid
  final List<IssueComment> comments;
  final List<Reaction> reactions;
  final String? redirect; // not null when metadata == null && !isDeleted
  final bool isDeleted;

  late final Set<String>? _labels;
  Set<String> get labels => _labels!; // only available when isValid

  late final String? _priority;
  String? get priority => _priority; // only available when isValid

  bool get isValid => _metadata != null;
  bool get isPullRequest => _metadata?.pullRequest != null;

  static Future<FullIssue> load({
    required final Directory cache,
    required final GitHub github,
    required final RepositorySlug repo,
    required final int issueNumber,
    final DateTime? cacheEpoch,
  }) async {
    final cacheData = await loadFromCache(
      cache,
      github,
      <String>['issue', repo.owner, repo.name, issueNumber.toString()],
      cacheEpoch,
      () async {
        try {
          final issue = await github.issues.get(repo, issueNumber);
          if (issue.url.startsWith(github.endpoint)) {
            if (issue.url !=
                '${github.endpoint}/repos/$repo/issues/$issueNumber') {
              return json.encode(<String, Object?>{'redirect': issue.url});
            }
          } else if (issue.url == '') {
            return json.encode(<String, Object?>{'deleted': true});
          }
          final comments = await github.issues
              .listCommentsByIssue(repo, issueNumber)
              .toList();
          final reactions = await github.issues
              .listReactions(repo, issueNumber)
              .toList();
          return json.encode(<String, Object?>{
            'issue': issue,
            'comments': comments,
            'reactions': reactions,
          });
        } on ClientException catch (e) {
          // print('\nIssue $issueNumber is a problem child (treating as deleted): $e');
          return json.encode(<String, Object?>{
            'deleted': true,
            'error': e.toString(),
          });
        }
      },
    );
    final data = json.decode(cacheData)! as Map<String, Object?>;
    if (data['redirect'] != null) {
      return FullIssue(
        repo,
        issueNumber,
        null,
        const <IssueComment>[],
        const <Reaction>[],
        redirect: data['redirect']! as String,
      );
    }
    if (data['deleted'] == true) {
      return FullIssue(
        repo,
        issueNumber,
        null,
        const <IssueComment>[],
        const <Reaction>[],
        isDeleted: true,
      );
    }
    final issue = Issue.fromJson(data['issue']! as Map<String, Object?>);
    return FullIssue(
      repo,
      issueNumber,
      issue,
      (data['comments']! as List<Object?>)
          .cast<Map<String, Object?>>()
          .map<IssueComment>(IssueComment.fromJson)
          .toList(),
      (data['reactions']! as List<Object?>)
          .cast<Map<String, Object?>>()
          .map<Reaction>(Reaction.fromJson)
          .toList(),
    );
  }

  @override
  String toString() {
    final result = StringBuffer();
    if (isValid) {
      result
        ..writeln('Issue $issueNumber (${metadata.state}): ${metadata.title}')
        ..writeln(metadata.htmlUrl)
        ..writeln(
          'Created by ${metadata.user!.login} on ${metadata.createdAt}, last updated on ${metadata.updatedAt}.',
        );
      // Temporary workaround for https://github.com/SpinlockLabs/github.dart/issues/401
      if (metadata.isClosed || metadata.state.toUpperCase() == 'CLOSED') {
        result.writeln(
          'Closed by ${metadata.closedBy?.login} on ${metadata.closedAt}.',
        );
        if (metadata.closedBy != null) {
          final user = metadata.closedBy!;
          result
            ..writeln('  avatarUrl: ${user.avatarUrl}')
            ..writeln('  bio: ${user.bio}')
            ..writeln('  blog: ${user.blog}')
            ..writeln('  company: ${user.company}')
            ..writeln('  createdAt: ${user.createdAt}')
            ..writeln('  email: ${user.email}')
            ..writeln('  followersCount: ${user.followersCount}')
            ..writeln('  followingCount: ${user.followingCount}')
            ..writeln('  hirable: ${user.hirable}')
            ..writeln('  htmlUrl: ${user.htmlUrl}')
            ..writeln('  id: ${user.id}')
            ..writeln('  location: ${user.location}')
            ..writeln('  login: ${user.login}')
            ..writeln('  name: ${user.name}')
            ..writeln('  publicGistsCount: ${user.publicGistsCount}')
            ..writeln('  publicReposCount: ${user.publicReposCount}')
            ..writeln('  siteAdmin: ${user.siteAdmin}')
            ..writeln('  twitterUsername: ${user.twitterUsername}')
            ..writeln('  updatedAt: ${user.updatedAt}');
        }
      }
      if (isPullRequest) {
        result.writeln('  Pull request: ${metadata.pullRequest?.diffUrl}');
      }
      result
        ..writeln(
          'Assignees: ${metadata.assignees!.map((final User user) => user.login!).join(', ')}',
        )
        ..writeln(
          'Labels: ${metadata.labels.map((final IssueLabel label) => label.name).join(', ')}',
        )
        ..writeln('Milestone: ${metadata.milestone ?? ""}');
    } else {
      result.writeln('Issue $issueNumber (redirected): see $redirect');
    }
    for (final comment in comments) {
      final line = comment.body!.split('\n').first;
      final body = line.substring(0, math.min(40, line.length));
      result.writeln(
        'Comment by ${comment.user!.login} at ${comment.createdAt}: $body',
      );
    }
    for (final reaction in reactions) {
      result.writeln(
        'Reaction: ${reaction.user!.login} ${reaction.content} at ${reaction.createdAt}',
      );
    }
    return result.toString();
  }
}

Future<void> fetchAllIssues(
  final GitHub github,
  final Directory cache,
  final RepositorySlug repo,
  final Duration issueMaxAge,
  final Map<int, FullIssue> results,
) async {
  var index = 1;
  var issues = 0;
  var prs = 0;
  var invalid = 0;
  final lastIssueNumberFile = cacheFileFor(cache, <String>[
    'issue',
    repo.owner,
    repo.name,
    'last',
  ]);
  var lastIssueNumber =
      await readFromFile<int>(lastIssueNumberFile, int.tryParse) ?? 0;
  var maxKnown = false;
  while (true) {
    try {
      final issue = await FullIssue.load(
        cache: cache,
        github: github,
        repo: repo,
        issueNumber: index,
        cacheEpoch: maxAge(issueMaxAge),
      );
      if (issue.isValid) {
        if (issue.isPullRequest) {
          prs += 1;
        } else {
          issues += 1;
        }
      } else if (issue.isDeleted) {
        throw NotFound(github, 'Issue $index deleted or not yet filed.');
      } else {
        // probably redirect
        invalid += 1;
      }
      results[index] = issue;
    } on FormatException catch (e) {
      print('\nIssue $index could not be processed: $e');
      invalid += 1;
    } on NotFound {
      if (index > lastIssueNumber) {
        final lastIssue = await github.issues
            .listByRepo(repo, state: 'all', sort: 'created', direction: 'desc')
            .first;
        lastIssueNumber = lastIssue.number;
        maxKnown = true;
        if (index > lastIssueNumber) {
          break;
        }
        invalid += 1;
      }
    }
    await rateLimit(
      github,
      '${repo.fullName}: #$index${lastIssueNumber > 0 ? " of ${maxKnown ? "" : "~"}$lastIssueNumber" : ""} ($issues issues; $prs PRs; $invalid errors)',
      'issue #${index + 1}',
    );
    index += 1;
  }
  await lastIssueNumberFile.writeAsString(lastIssueNumber.toString());
  stdout.write('\x1B[K\r');
}

Future<void> updateAllIssues(
  final GitHub github,
  final Directory cache,
  final RepositorySlug repo,
  final Map<int, FullIssue> issues,
) async {
  final pendingIssues = issues.isEmpty ? <int>{} : issues.keys.toSet();
  var highestKnownIssue = pendingIssues.isEmpty
      ? 0
      : (pendingIssues.toList()..sort()).last;
  final updateStampFile = cacheFileFor(cache, <String>[
    'issue',
    repo.owner,
    repo.name,
    'last-update',
  ]);
  final lastFullScanStartTime = await readFromFile<DateTime>(
    updateStampFile,
    DateTime.tryParse,
  );
  DateTime? thisFullScanStartTime;
  var count = 0;
  await rateLimit(
    github,
    '${repo.fullName}: fetching issues with recent changes',
    'scan',
  );
  await for (final Issue summary in github.issues.listByRepo(
    repo,
    state: 'all',
    sort: 'updated',
    direction: 'desc',
    perPage: 100,
  )) {
    if (summary.updatedAt != null) {
      thisFullScanStartTime ??= summary.updatedAt!;
    }
    if (mode == Mode.abbreviated &&
        summary.updatedAt != null &&
        lastFullScanStartTime != null &&
        summary.updatedAt!.isBefore(lastFullScanStartTime)) {
      stdout.write('\x1B[K\r');
      return;
    }
    const maxRetry = 5;
    for (var retry = 1; retry <= maxRetry; retry += 1) {
      try {
        final String parenthetical;
        var delta = lastFullScanStartTime?.difference(summary.updatedAt!);
        if (delta != null && delta.inMilliseconds < 0) {
          delta = -delta;
          if (delta.inDays > 2) {
            parenthetical = '${delta.inDays} days remaining';
          } else if (delta.inHours > 2) {
            parenthetical = '${delta.inHours} hours remaining';
          } else if (delta.inMinutes > 2) {
            parenthetical = '${delta.inMinutes} minutes remaining';
          } else {
            parenthetical = '${delta.inMilliseconds}ms remaining';
          }
        } else {
          parenthetical =
              '${100 * count ~/ (pendingIssues.length + count)}% newer than ${summary.updatedAt}';
        }
        await rateLimit(
          github,
          '${repo.fullName}: $count issues updated ($parenthetical)',
          'scan',
        );
        final issue = await FullIssue.load(
          cache: cache,
          github: github,
          repo: repo,
          issueNumber: summary.number,
          cacheEpoch: summary.updatedAt,
        );
        assert(
          !issue.isValid ||
              !issue.metadata.updatedAt!.isBefore(summary.updatedAt!),
          'invariant violation\nOLD DATA:\n${json.encode(issue.metadata.toJson())}\nNEW DATA:\n${json.encode(summary.toJson())}',
        );
        if (issue.issueNumber > highestKnownIssue) {
          for (
            var index = highestKnownIssue;
            index < issue.issueNumber;
            index += 1
          ) {
            pendingIssues.add(index);
          }
          highestKnownIssue = issue.issueNumber;
        } else {
          pendingIssues.remove(issue.issueNumber);
        }
        issues[issue.issueNumber] = issue;
        break;
      } on FormatException catch (e) {
        print(
          '\nError while updating issue #${summary.number} (attempt $retry/$maxRetry): $e',
        );
      }
    }
    count += 1;
  }
  stdout.write('\x1B[K\r');
  if (pendingIssues.isNotEmpty) {
    // looks like these went away, so force fetch them
    var count = 0;
    for (final issueNumber in pendingIssues) {
      await rateLimit(
        github,
        '${repo.fullName}: $count / ${pendingIssues.length} missing issues checked',
        'issue #$issueNumber',
      );
      try {
        issues[issueNumber] = await FullIssue.load(
          cache: cache,
          github: github,
          repo: repo,
          issueNumber: issueNumber,
          cacheEpoch: lastFullScanStartTime,
        );
        count += 1;
      } on Exception catch (e) {
        print('\nError while updating issue #$issueNumber: $e');
      }
    }
    stdout.write('\x1B[K\r');
  }
  if (thisFullScanStartTime != null) {
    await updateStampFile.writeAsString(
      thisFullScanStartTime.toIso8601String(),
    );
  }
}
