// 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 'package:appengine/appengine.dart';
import 'package:gcloud/db.dart';
import 'package:meta/meta.dart';

import '../datastore/cocoon_config.dart';
import '../model/appengine/benchmark_data.dart';
import '../model/appengine/commit.dart';
import '../model/appengine/key_converter.dart';
import '../model/appengine/key_helper.dart';
import '../model/appengine/time_series.dart';
import '../model/appengine/time_series_entity.dart';
import '../model/appengine/time_series_value.dart';
import '../request_handling/body.dart';
import '../request_handling/exceptions.dart';
import '../request_handling/no_auth_request_handler.dart';
import '../service/datastore.dart';

@immutable
class GetTimeSeriesHistory
    extends NoAuthRequestHandler<GetTimeSeriesHistoryResponse> {
  const GetTimeSeriesHistory(
    Config config, {
    @visibleForTesting DatastoreServiceProvider datastoreProvider,
  })  : datastoreProvider =
            datastoreProvider ?? DatastoreService.defaultProvider,
        super(config: config);

  final DatastoreServiceProvider datastoreProvider;
  static const String timeSeriesKeyParam = 'TimeSeriesKey';
  static const String startFromParam = 'StartFrom';

  @override
  Future<GetTimeSeriesHistoryResponse> post() async {
    checkRequiredParameters(<String>[timeSeriesKeyParam]);
    // This number inherites from earlier GO backend. Up to change if necessary.
    const int maxRecords = 6000;
    final DatastoreService datastore = datastoreProvider(config.db);
    final KeyHelper keyHelper = KeyHelper(
        applicationContext: AppEngineContext(false, '', '', '', '', '', Uri()));
    final Set<Commit> commits =
        await datastore.queryRecentCommits(limit: maxRecords).toSet();

    Key timeSeriesKey;
    try {
      timeSeriesKey =
          keyHelper.decode(requestData[timeSeriesKeyParam] as String);
    } on FormatException {
      throw BadRequestException(
          'Bad timeSeries key: ${requestData[timeSeriesKeyParam]}');
    }

    final TimeSeries timeSeries =
        await config.db.lookupValue<TimeSeries>(timeSeriesKey, orElse: () {
      throw BadRequestException('No such timeseries: ${timeSeriesKey.id}');
    });

    List<TimeSeriesValue> timeSeriesValues = await datastore
        .queryRecentTimeSeriesValues(timeSeries,
            startFrom: startFromParam, limit: maxRecords)
        .toList();
    timeSeriesValues = insertMissingTimeseriesValues(timeSeriesValues, commits);

    return GetTimeSeriesHistoryResponse(timeSeries, timeSeriesValues);
  }
}

@immutable
class GetTimeSeriesHistoryResponse extends JsonBody {
  const GetTimeSeriesHistoryResponse(this.timeSeries, this.timeSeriesValues)
      : assert(timeSeries != null);

  final TimeSeries timeSeries;
  final List<TimeSeriesValue> timeSeriesValues;

  @override
  Map<String, dynamic> toJson() {
    return <String, dynamic>{
      'BenchmarkData': BenchmarkData(
          timeSeriesEntity: TimeseriesEntity(
              timeSeries: timeSeries,
              key: const KeyConverter().toJson(timeSeries.key)),
          values: timeSeriesValues),
      // TODO(keyonghan): implemement last position
      // https://github.com/flutter/flutter/issues/42362
      'LastPosition': null,
    };
  }
}

List<TimeSeriesValue> insertMissingTimeseriesValues(
    List<TimeSeriesValue> timeSerialsValues, Set<Commit> commits) {
  final List<TimeSeriesValue> values = <TimeSeriesValue>[];
  final Map<String, TimeSeriesValue> valuesByCommit =
      <String, TimeSeriesValue>{};
  for (TimeSeriesValue value in timeSerialsValues) {
    valuesByCommit[value.revision] = value;
  }

  for (Commit commit in commits) {
    TimeSeriesValue value;

    if (valuesByCommit.containsKey(commit.sha)) {
      value = valuesByCommit[commit.sha];
      // This logic inherites from earlier GO backend. Up to change if necessary.
      if (value.value < 0) {
        value.value = 0;
      }
    } else {
      // Insert placeholder entries for missing values.
      // Missing values happen when there is any queried timeSeriesValue
      // whose commit does not appear in the queried top [maxRecords] commits
      value = TimeSeriesValue(
        revision: commit.sha,
        createTimestamp: commit.timestamp,
        dataMissing: true,
        value: 0,
      );
    }
    values.add(value);
  }
  return values;
}
