// Copyright (c) 2021, 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.

// @dart=2.9

import 'dart:async';
import 'dart:io';
import 'dart:math';

import 'package:pedantic/pedantic.dart';

/// An HTTP client wrapper that times out connections and requests and
/// automatically retries failing requests.
class RetryTimeoutClient {
  /// The wrapped client.
  final HttpClient _inner;

  /// The number of times a request should be retried.
  final int _retries;

  /// The callback that determines whether a request should be retried.
  final bool Function(HttpClientResponse) _when;

  /// The callback that determines whether a request when an error is thrown.
  final bool Function(Object, StackTrace) _whenError;

  /// The callback that determines how long to wait before retrying a request.
  final Duration Function(int) _delay;

  /// The callback that determines when to cancel a connection.
  final Duration Function(int) _connectionTimeout;

  /// The callback that determines when to cancel a request.
  final Duration Function(int) _reponseTimeout;

  /// The callback to call to indicate that a request is being retried.
  final void Function(Uri, HttpClientResponse, int) _onRetry;

  /// Creates a client wrapping [_inner] that retries HTTP requests.
  RetryTimeoutClient(
    this._inner, {
    int retries = 3,
    bool Function(HttpClientResponse) when = _defaultWhen,
    bool Function(Object, StackTrace) whenError = _defaultWhenError,
    Duration Function(int retryCount) delay = _defaultDelay,
    Duration Function(int retryCount) connectionTimeout = _defaultTimeout,
    Duration Function(int retryCount) responseTimeout = _defaultTimeout,
    void Function(Uri, HttpClientResponse, int retryCount) onRetry,
  })  : _retries = retries,
        _when = when,
        _whenError = whenError,
        _delay = delay,
        _connectionTimeout = connectionTimeout,
        _reponseTimeout = responseTimeout,
        _onRetry = onRetry {
    RangeError.checkNotNegative(_retries, 'retries');
  }

  Future<HttpClientResponse> headUrl(Uri url) {
    return _retry(url, _inner.headUrl);
  }

  Future<HttpClientResponse> getUrl(Uri url) {
    return _retry(url, _inner.getUrl);
  }

  Future<HttpClientResponse> _retry(
      Uri url, Future<HttpClientRequest> Function(Uri) method) async {
    var i = 0;
    for (;;) {
      HttpClientResponse response;
      try {
        _inner.connectionTimeout = _connectionTimeout(i);
        var request = await method(url).timeout(
          _reponseTimeout(i),
          onTimeout: () =>
              throw TimeoutException('$url, retry:$i', _reponseTimeout(i)),
        );
        response = await request.close();
      } catch (error, stackTrace) {
        if (i == _retries || !_whenError(error, stackTrace)) rethrow;
      }

      if (response != null) {
        if (i == _retries || !_when(response)) return response;

        // Make sure the response stream is listened to so that we don't leave
        // dangling connections.
        unawaited(response.listen((_) {}).cancel().catchError((_) {}));
      }

      await Future.delayed(_delay(i));
      _onRetry?.call(url, response, i);
      i++;
    }
  }

  void close({bool force = false}) => _inner.close(force: force);
}

bool _defaultWhen(HttpClientResponse response) =>
    response.statusCode == 500 || response.statusCode == 503;

bool _defaultWhenError(Object error, StackTrace stackTrace) =>
    error is OSError ||
    error is HttpException ||
    error is SocketException ||
    error is TimeoutException;

Duration _defaultDelay(int retryCount) =>
    const Duration(milliseconds: 500) * pow(1.5, retryCount);

Duration _defaultTimeout(int retryCount) =>
    const Duration(milliseconds: 5000) * pow(1.5, retryCount);
