// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. 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:collection';
import 'dart:math' as math;

import '../usage.dart';
import '../uuid/uuid.dart';

String postEncode(Map<String, dynamic> map) {
  // &foo=bar
  return map.keys.map((key) {
    var value = '${map[key]}';
    return '${key}=${Uri.encodeComponent(value)}';
  }).join('&');
}

/// A throttling algorithm. This models the throttling after a bucket with
/// water dripping into it at the rate of 1 drop per second. If the bucket has
/// water when an operation is requested, 1 drop of water is removed and the
/// operation is performed. If not the operation is skipped. This algorithm
/// lets operations be performed in bursts without throttling, but holds the
/// overall average rate of operations to 1 per second.
class ThrottlingBucket {
  final int startingCount;
  int drops;
  late int _lastReplenish;

  ThrottlingBucket(this.startingCount) : drops = startingCount {
    _lastReplenish = DateTime.now().millisecondsSinceEpoch;
  }

  bool removeDrop() {
    _checkReplenish();

    if (drops <= 0) {
      return false;
    } else {
      drops--;
      return true;
    }
  }

  void _checkReplenish() {
    final now = DateTime.now().millisecondsSinceEpoch;

    if (_lastReplenish + 1000 < now) {
      final inc = (now - _lastReplenish) ~/ 1000;
      drops = math.min(drops + inc, startingCount);
      _lastReplenish += (1000 * inc);
    }
  }
}

class AnalyticsImpl implements Analytics {
  static const String _defaultAnalyticsUrl =
      'https://www.google-analytics.com/collect';

  static const String _defaultAnalyticsBatchingUrl =
      'https://www.google-analytics.com/batch';

  @override
  final String trackingId;
  @override
  final String? applicationName;
  @override
  final String? applicationVersion;

  final PersistentProperties properties;
  final PostHandler postHandler;

  final ThrottlingBucket _bucket = ThrottlingBucket(20);
  final Map<String, dynamic> _variableMap = {};

  final List<Future> _futures = [];

  @override
  AnalyticsOpt analyticsOpt = AnalyticsOpt.optOut;

  late Duration _batchingDelay;
  final Queue<String> _batchedEvents = Queue<String>();
  bool _isSendingScheduled = false;

  late final String _url;
  late final String _batchingUrl;

  final StreamController<Map<String, dynamic>> _sendController =
      StreamController.broadcast(sync: true);

  AnalyticsImpl(
    this.trackingId,
    this.properties,
    this.postHandler, {
    this.applicationName,
    this.applicationVersion,
    String? analyticsUrl,
    String? analyticsBatchingUrl,
    Duration? batchingDelay,
  }) {
    if (applicationName != null) setSessionValue('an', applicationName);
    if (applicationVersion != null) setSessionValue('av', applicationVersion);

    _url = analyticsUrl ?? _defaultAnalyticsUrl;
    _batchingUrl = analyticsBatchingUrl ?? _defaultAnalyticsBatchingUrl;
    _batchingDelay = batchingDelay ?? const Duration();
  }

  bool? _firstRun;

  @override
  bool get firstRun {
    if (_firstRun == null) {
      _firstRun = properties['firstRun'] == null;

      if (properties['firstRun'] != false) {
        properties['firstRun'] = false;
      }
    }

    return _firstRun!;
  }

  @override
  bool get enabled {
    var optIn = analyticsOpt == AnalyticsOpt.optIn;
    return optIn
        ? properties['enabled'] == true
        : properties['enabled'] != false;
  }

  @override
  set enabled(bool value) {
    properties['enabled'] = value;
  }

  @override
  Future sendScreenView(String viewName, {Map<String, String>? parameters}) {
    var args = <String, String>{'cd': viewName, ...?parameters};
    return _enqueuePayload('screenview', args);
  }

  @override
  Future sendEvent(String category, String action,
      {String? label, int? value, Map<String, String>? parameters}) {
    final args = <String, String>{
      'ec': category,
      'ea': action,
      if (label != null) 'el': label,
      if (value != null) 'ev': value.toString(),
      ...?parameters
    };

    return _enqueuePayload('event', args);
  }

  @override
  Future sendSocial(String network, String action, String target) {
    var args = <String, String>{'sn': network, 'sa': action, 'st': target};
    return _enqueuePayload('social', args);
  }

  @override
  Future sendTiming(String variableName, int time,
      {String? category, String? label}) {
    var args = <String, String>{
      'utv': variableName,
      'utt': time.toString(),
      if (label != null) 'utl': label,
      if (category != null) 'utc': category,
    };

    return _enqueuePayload('timing', args);
  }

  @override
  AnalyticsTimer startTimer(String variableName,
      {String? category, String? label}) {
    return AnalyticsTimer(this, variableName, category: category, label: label);
  }

  @override
  Future sendException(String description, {bool? fatal}) {
    // We trim exceptions to a max length; google analytics will apply it's own
    // truncation, likely around 150 chars or so.
    const maxExceptionLength = 1000;

    // In order to ensure that the client of this API is not sending any PII
    // data, we strip out any stack trace that may reference a path on the
    // user's drive (file:/...).
    if (description.contains('file:/')) {
      description = description.substring(0, description.indexOf('file:/'));
    }

    description = description.replaceAll('\n', '; ');

    if (description.length > maxExceptionLength) {
      description = description.substring(0, maxExceptionLength);
    }

    var args = <String, String>{
      'exd': description,
      if (fatal != null && fatal) 'exf': '1',
    };
    return _enqueuePayload('exception', args);
  }

  @override
  dynamic getSessionValue(String param) => _variableMap[param];

  @override
  void setSessionValue(String param, dynamic value) {
    if (value == null) {
      _variableMap.remove(param);
    } else {
      _variableMap[param] = value;
    }
  }

  @override
  Stream<Map<String, dynamic>> get onSend => _sendController.stream;

  @override
  Future<List<dynamic>> waitForLastPing({Duration? timeout}) async {
    // If there are pending messages, send them now.
    if (_batchedEvents.isNotEmpty) {
      _trySendBatches(Completer<void>());
    }
    var f = Future.wait(_futures);
    if (timeout != null) f = f.timeout(timeout);
    return f;
  }

  @override
  void close() => postHandler.close();

  @override
  String get clientId => properties['clientId'] ??= Uuid().generateV4();

  /// Send raw data to analytics. Callers should generally use one of the typed
  /// methods (`sendScreenView`, `sendEvent`, ...).
  ///
  /// Valid values for [hitType] are: 'pageview', 'screenview', 'event',
  /// 'transaction', 'item', 'social', 'exception', and 'timing'.
  Future sendRaw(String hitType, Map<String, dynamic> args) {
    return _enqueuePayload(hitType, args);
  }

  /// Puts a single hit in the queue. If the queue was empty - start waiting
  /// for the result of [_batchingDelay] before sending all enqueued events.
  ///
  /// Valid values for [hitType] are: 'pageview', 'screenview', 'event',
  /// 'transaction', 'item', 'social', 'exception', and 'timing'.
  Future<void> _enqueuePayload(
    String hitType,
    Map<String, dynamic> args,
  ) async {
    if (!enabled) return;
    // TODO(sigurdm): Really all the 'send' methods should not return Futures
    // there is not much point in waiting for it. Only [waitForLastPing].
    final completer = Completer<void>();
    final eventArgs = <String, String>{
      ...args,
      ..._variableMap,
      'v': '1', // protocol version
      'tid': trackingId,
      'cid': clientId,
      't': hitType,
    };

    _sendController.add(eventArgs);
    _batchedEvents.add(postHandler.encodeHit(eventArgs));
    // First check if we have a full batch - if so, send them immediately.
    if (_batchedEvents.length >= _maxHitsPerBatch ||
        _batchedEvents.fold<int>(0, (s, e) => s + e.length) >=
            _maxBytesPerBatch) {
      _trySendBatches(completer);
    } else if (!_isSendingScheduled) {
      _isSendingScheduled = true;
      // ignore: unawaited_futures
      Future.delayed(_batchingDelay).then((value) {
        _isSendingScheduled = false;
        _trySendBatches(completer);
      });
    }
    return completer.future;
  }

  // Send no more than 20 messages per batch.
  static const _maxHitsPerBatch = 20;
  // Send no more than 16K per batch.
  static const _maxBytesPerBatch = 16000;

  void _trySendBatches(Completer<void> completer) {
    final futures = <Future>[];
    while (_batchedEvents.isNotEmpty) {
      final batch = <String>[];
      final totalLength = 0;

      while (true) {
        if (_batchedEvents.isEmpty) break;
        if (totalLength + _batchedEvents.first.length > _maxBytesPerBatch) {
          break;
        }
        batch.add(_batchedEvents.removeFirst());
        if (batch.length == _maxHitsPerBatch) break;
      }
      if (_bucket.removeDrop()) {
        final future = postHandler.sendPost(
            batch.length == 1 ? _url : _batchingUrl, batch);
        _recordFuture(future);
        futures.add(future);
      }
    }
    completer.complete(Future.wait(futures).then((_) {}));
  }

  void _recordFuture(Future f) {
    _futures.add(f);
    f.whenComplete(() => _futures.remove(f));
  }
}

/// A persistent key/value store. An [AnalyticsImpl] instance expects to have
/// one of these injected into it.
///
/// There are default implementations for `dart:io` and `dart:html` clients.
///
/// The [name] parameter is used to uniquely store these properties on disk /
/// persistent storage.
abstract class PersistentProperties {
  final String name;

  PersistentProperties(this.name);

  dynamic operator [](String key);

  void operator []=(String key, dynamic value);

  /// Re-read settings from the backing store. This may be a no-op on some
  /// platforms.
  void syncSettings();
}

/// A utility class to perform HTTP POSTs.
///
/// An [AnalyticsImpl] instance expects to have one of these injected into it.
/// There are default implementations for `dart:io` and `dart:html` clients.
///
/// The POST information should be sent on a best-effort basis.
///
/// The `Future` from [sendPost] should complete when the operation is finished,
/// but failures to send the information should be silent.
abstract class PostHandler {
  Future sendPost(String url, List<String> batch);
  String encodeHit(Map<String, String> hit);

  /// Free any used resources.
  void close();
}
