// 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:async';
import 'dart:math';

import 'package:gcloud/datastore.dart' as gcloud_datastore;
import 'package:gcloud/db.dart';
import 'package:github/github.dart' show RepositorySlug, PullRequest;
import 'package:grpc/grpc.dart';
import 'package:meta/meta.dart';
import 'package:retry/retry.dart';

import '../model/appengine/branch.dart';
import '../model/appengine/commit.dart';
import '../model/appengine/github_build_status_update.dart';
import '../model/appengine/github_gold_status_update.dart';
import '../model/appengine/stage.dart';
import '../model/appengine/task.dart';
import 'config.dart';

/// Per the docs in [DatastoreDB.withTransaction], only 5 entity groups can
/// be touched in any given transaction, or the backing datastore will throw
/// an error.
const int defaultMaxEntityGroups = 5;

/// This number inherits from old GO backend, and is upto change if necessary.
const int defaultTimeSeriesValuesNumber = 1500;

/// Function signature for a [DatastoreService] provider.
typedef DatastoreServiceProvider = DatastoreService Function(DatastoreDB db);

/// Function signature that will be executed with retries.
typedef RetryHandler = Function();

/// Runs a db transaction with retries.
///
/// It uses quadratic backoff starting with 200ms and 3 max attempts.
/// for context please read https://github.com/flutter/flutter/issues/54615.
Future<void> runTransactionWithRetries(RetryHandler retryHandler, {RetryOptions? retryOptions}) {
  final RetryOptions r = retryOptions ??
      const RetryOptions(
        maxDelay: Duration(seconds: 10),
        maxAttempts: 3,
      );
  return r.retry(
    retryHandler,
    retryIf: (Exception e) => e is gcloud_datastore.TransactionAbortedError || e is GrpcError,
  );
}

/// Service class for interacting with App Engine cloud datastore.
///
/// This service exists to provide an API for common datastore queries made by
/// the Cocoon backend.
@immutable
class DatastoreService {
  /// Creates a new [DatastoreService].
  ///
  /// The [db] argument must not be null.
  const DatastoreService(this.db, this.maxEntityGroups, {RetryOptions? retryOptions})
      : retryOptions = retryOptions ??
            const RetryOptions(
              maxDelay: Duration(seconds: 10),
              maxAttempts: 3,
            );

  /// Maximum number of entity groups to process at once.
  final int maxEntityGroups;

  /// The backing [DatastoreDB] object.
  final DatastoreDB db;

  /// Transaction retry configurations.
  final RetryOptions retryOptions;

  /// Creates and returns a [DatastoreService] using [db] and [maxEntityGroups].
  static DatastoreService defaultProvider(DatastoreDB db) {
    return DatastoreService(db, defaultMaxEntityGroups);
  }

  /// Queries for recent commits.
  ///
  /// The [limit] argument specifies the maximum number of commits to retrieve.
  ///
  /// The returned commits will be ordered by most recent [Commit.timestamp].
  Stream<Commit> queryRecentCommits({
    int limit = 100,
    int? timestamp,
    String? branch,
    required RepositorySlug slug,
  }) {
    timestamp ??= DateTime.now().millisecondsSinceEpoch;
    branch ??= Config.defaultBranch(slug);
    final Query<Commit> query = db.query<Commit>()
      ..limit(limit)
      ..filter('repository =', slug.fullName)
      ..filter('branch =', branch)
      ..order('-timestamp')
      ..filter('timestamp <', timestamp);
    return query.run();
  }

  Stream<Branch> queryBranches() {
    final Query<Branch> query = db.query<Branch>();
    return query.run();
  }

  /// Queries for recent [Task] by name.
  ///
  /// The [limit] argument specifies the maximum number of tasks to retrieve.
  ///
  /// The returned tasks will be ordered by most recent to oldest.
  Stream<Task> queryRecentTasksByName({
    int limit = 100,
    required String name,
  }) {
    final Query<Task> query = db.query<Task>()
      ..limit(limit)
      ..filter('name =', name)
      ..order('-createTimestamp');
    return query.run();
  }

  /// Queries for recent tasks that meet the specified criteria.
  ///
  /// Since each task belongs to a commit, this query implicitly includes a
  /// query of the most recent N commits (see [queryRecentCommits]). The
  /// [commitLimit] argument specifies how many commits to consider when
  /// retrieving the list of recent tasks.
  ///
  /// If [taskName] is specified, only tasks whose [Task.name] matches the
  /// specified value will be returned. By default, tasks will be returned
  /// regardless of their name.
  ///
  /// The returned tasks will be ordered by most recent [Commit.timestamp]
  /// first, then by most recent [Task.createTimestamp].
  Stream<FullTask> queryRecentTasks({
    String? taskName,
    int commitLimit = 20,
    String? branch,
    required RepositorySlug slug,
  }) async* {
    await for (Commit commit in queryRecentCommits(limit: commitLimit, branch: branch, slug: slug)) {
      final Query<Task> query = db.query<Task>(ancestorKey: commit.key)..order('-createTimestamp');
      if (taskName != null) {
        query.filter('name =', taskName);
      }
      yield* query.run().map<FullTask>((Task task) => FullTask(task, commit));
    }
  }

  /// Finds all tasks owned by the specified [commit] and partitions them into
  /// stages.
  ///
  /// The returned list of stages will be ordered by the natural ordering of
  /// [Stage].
  Future<List<Stage>> queryTasksGroupedByStage(Commit commit) async {
    final Query<Task> query = db.query<Task>(ancestorKey: commit.key)..order('-stageName');
    final Map<String?, StageBuilder> stages = <String?, StageBuilder>{};
    await for (Task task in query.run()) {
      if (!stages.containsKey(task.stageName)) {
        stages[task.stageName] = StageBuilder()
          ..commit = commit
          ..name = task.stageName;
      }
      stages[task.stageName]!.tasks.add(task);
    }
    final List<Stage> result = stages.values.map<Stage>((StageBuilder stage) => stage.build()).toList();
    return result..sort();
  }

  Future<GithubBuildStatusUpdate> queryLastStatusUpdate(
    RepositorySlug slug,
    PullRequest pr,
  ) async {
    final Query<GithubBuildStatusUpdate> query = db.query<GithubBuildStatusUpdate>()
      ..filter('repository =', slug.fullName)
      ..filter('pr =', pr.number)
      ..filter('head =', pr.head!.sha);
    final List<GithubBuildStatusUpdate> previousStatusUpdates = await query.run().toList();

    if (previousStatusUpdates.isEmpty) {
      return GithubBuildStatusUpdate(
        key: db.emptyKey.append<int>(GithubBuildStatusUpdate),
        repository: slug.fullName,
        pr: pr.number!,
        head: pr.head!.sha,
        updates: 0,
        updateTimeMillis: DateTime.now().millisecondsSinceEpoch,
      );
    } else {
      /// Duplicate cases rarely happen. It happens only when race condition
      /// occurs in app engine. When multiple records exist, the latest one
      /// is returned.
      if (previousStatusUpdates.length > 1) {
        return previousStatusUpdates.reduce((GithubBuildStatusUpdate current, GithubBuildStatusUpdate next) =>
            current.updateTimeMillis! < next.updateTimeMillis! ? next : current);
      }
      return previousStatusUpdates.single;
    }
  }

  Future<GithubGoldStatusUpdate> queryLastGoldUpdate(
    RepositorySlug slug,
    PullRequest pr,
  ) async {
    final Query<GithubGoldStatusUpdate> query = db.query<GithubGoldStatusUpdate>()
      ..filter('repository =', slug.fullName)
      ..filter('pr =', pr.number);
    final List<GithubGoldStatusUpdate> previousStatusUpdates = await query.run().toList();

    if (previousStatusUpdates.isEmpty) {
      return GithubGoldStatusUpdate(
        pr: pr.number!,
        head: '',
        status: '',
        updates: 0,
        description: '',
        repository: slug.fullName,
      );
    } else {
      if (previousStatusUpdates.length > 1) {
        throw StateError('GithubGoldStatusUpdate should have no more than one entry on '
            'repository ${slug.fullName}, pr ${pr.number}.');
      }
      return previousStatusUpdates.single;
    }
  }

  /// Shards [rows] into several sublists of size [maxEntityGroups].
  Future<List<List<Model<dynamic>>>> shard(List<Model<dynamic>> rows) async {
    final List<List<Model<dynamic>>> shards = <List<Model<dynamic>>>[];
    for (int i = 0; i < rows.length; i += maxEntityGroups) {
      shards.add(rows.sublist(i, i + min<int>(rows.length - i, maxEntityGroups)));
    }
    return shards;
  }

  /// Inserts [rows] into datastore sharding the inserts if needed.
  Future<void> insert(List<Model<dynamic>> rows) async {
    final List<List<Model<dynamic>>> shards = await shard(rows);
    for (List<Model<dynamic>> shard in shards) {
      await runTransactionWithRetries(() async {
        await db.withTransaction<void>((Transaction transaction) async {
          transaction.queueMutations(inserts: shard);
          await transaction.commit();
        });
      }, retryOptions: retryOptions);
    }
  }

  /// Looks up registers by [keys].
  Future<List<T?>> lookupByKey<T extends Model<dynamic>>(List<Key<dynamic>> keys) async {
    List<T?> results = <T>[];
    await runTransactionWithRetries(() async {
      await db.withTransaction<void>((Transaction transaction) async {
        results = await transaction.lookup<T>(keys);
      });
    }, retryOptions: retryOptions);
    return results;
  }

  /// Looks up registers by value using a single [key].
  Future<T> lookupByValue<T extends Model<dynamic>>(Key<dynamic> key, {T Function()? orElse}) async {
    late T result;
    await runTransactionWithRetries(() async {
      await db.withTransaction<void>((Transaction transaction) async {
        result = await db.lookupValue<T>(key, orElse: orElse);
      });
    }, retryOptions: retryOptions);
    return result;
  }

  /// Runs a function inside a transaction providing a [Transaction] parameter.
  Future<T?> withTransaction<T>(Future<T> Function(Transaction) handler) async {
    T? result;
    await runTransactionWithRetries(() async {
      await db.withTransaction<void>((Transaction transaction) async {
        result = await handler(transaction);
      });
    }, retryOptions: retryOptions);
    return result;
  }
}
