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

/// Helpers for dealing with HTTP.
library;

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

import 'package:collection/collection.dart';
import 'package:http/http.dart' as http;
import 'package:pool/pool.dart';

import 'log.dart' as log;
import 'sdk.dart';
import 'utils.dart';

/// Headers and field names that should be censored in the log output.
const _censoredFields = ['refresh_token', 'authorization'];

/// Headers required for pub.dev API requests.
///
/// The Accept header tells pub.dev which version of the API we're
/// expecting, so it can either serve that version or give us a 406 error if
/// it's not supported.
const pubApiHeaders = {'Accept': 'application/vnd.pub.v2+json'};

/// An HTTP client that transforms 40* errors and socket exceptions into more
/// user-friendly error messages.
class _PubHttpClient extends http.BaseClient {
  final _requestStopwatches = <http.BaseRequest, Stopwatch>{};

  http.Client _inner;

  /// We manually keep track of whether the client was closed,
  /// indicating that no more networking should be done. (And thus we don't need
  /// to retry failed requests).
  bool _wasClosed = false;

  _PubHttpClient([http.Client? inner]) : _inner = inner ?? http.Client();

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) async {
    if (_wasClosed) {
      throw StateError('Attempting to send request on closed client');
    }
    request.headers[HttpHeaders.userAgentHeader] = 'Dart pub ${sdk.version}';
    if (request.url.host == 'localhost') {
      // We always prefer using ipv4 over ipv6 for 'localhost'.
      //
      // This prevents conflicts where the same port is occupied by the same
      // port on localhost.
      final resolutions = await InternetAddress.lookup('localhost');
      final ipv4Address = resolutions.firstWhereOrNull(
        (a) => a.type == InternetAddressType.IPv4,
      );
      if (ipv4Address != null) {
        request = _OverrideUrlRequest(
          request.url.replace(host: ipv4Address.host),
          request,
        );
      }
    }
    _requestStopwatches[request] = Stopwatch()..start();
    _logRequest(request);
    final http.StreamedResponse streamedResponse;
    try {
      streamedResponse = await _inner.send(request);
    } on http.ClientException {
      if (_wasClosed) {
        // Avoid retrying in this case.
        throw _ClientClosedException();
      }
      rethrow;
    }

    _logResponse(streamedResponse);

    return streamedResponse;
  }

  /// Logs the fact that [request] was sent, and information about it.
  void _logRequest(http.BaseRequest request) {
    final requestLog = StringBuffer();
    requestLog.writeln('HTTP ${request.method} ${request.url}');
    request.headers.forEach(
      (name, value) => requestLog.writeln(_logField(name, value)),
    );

    if (request.method == 'POST') {
      final contentTypeString = request.headers[HttpHeaders.contentTypeHeader];
      final contentType = ContentType.parse(contentTypeString ?? '');
      if (request is http.MultipartRequest) {
        requestLog.writeln();
        requestLog.writeln('Body fields:');
        request.fields.forEach(
          (name, value) => requestLog.writeln(_logField(name, value)),
        );

        // TODO(nweiz): make MultipartRequest.files readable, and log them?
      } else if (request is http.Request) {
        if (contentType.value == 'application/x-www-form-urlencoded') {
          requestLog.writeln();
          requestLog.writeln('Body fields:');
          request.bodyFields.forEach(
            (name, value) => requestLog.writeln(_logField(name, value)),
          );
        } else if (contentType.value == 'text/plain' ||
            contentType.value == 'application/json') {
          requestLog.write(request.body);
        }
      }
    }

    log.io(requestLog.toString().trim());
  }

  /// Logs the fact that [response] was received, and information about it.
  void _logResponse(http.StreamedResponse response) {
    // TODO(nweiz): Fork the response stream and log the response body. Be
    // careful not to log OAuth2 private data, though.

    final responseLog = StringBuffer();
    final request = response.request!;
    final stopwatch = _requestStopwatches.remove(request)!..stop();
    responseLog.writeln(
      'HTTP response ${response.statusCode} '
      '${response.reasonPhrase} for ${request.method} ${request.url}',
    );
    responseLog.writeln('took ${stopwatch.elapsed}');
    response.headers.forEach(
      (name, value) => responseLog.writeln(_logField(name, value)),
    );

    log.io(responseLog.toString().trim());
  }

  /// Returns a log-formatted string for the HTTP field or header with the given
  /// [name] and [value].
  String _logField(String name, String value) {
    if (_censoredFields.contains(name.toLowerCase())) {
      return '$name: <censored>';
    } else {
      return '$name: $value';
    }
  }

  @override
  void close() {
    _wasClosed = true;
    _inner.close();
  }
}

/// The [_PubHttpClient] wrapped by [globalHttpClient].
final _pubClient = _PubHttpClient();

/// The HTTP client to use for all HTTP requests.
final globalHttpClient = _pubClient;

/// The underlying HTTP client wrapped by [globalHttpClient].
/// This enables the ability to use a mock client in tests.
http.Client get innerHttpClient => _pubClient._inner;
set innerHttpClient(http.Client client) => _pubClient._inner = client;

extension AttachHeaders on http.Request {
  /// Adds headers required for pub.dev API requests.
  void attachPubApiHeaders() {
    headers.addAll(pubApiHeaders);
  }
}

/// Handles a successful JSON-formatted response from pub.dev.
///
/// These responses are expected to be of the form `{"success": {"message":
/// "some message"}}`. If the format is correct, the message will be printed;
/// otherwise an error will be raised.
void handleJsonSuccess(http.Response response) {
  switch (parseJsonResponse(response)) {
    case {'success': {'message': final String message}}:
      log.message(
        'Message from server: ${log.green(sanitizeForTerminal(message))}',
      );
    default:
      invalidServerResponse(response);
  }
}

/// Handles an unsuccessful JSON-formatted response from pub.dev.
///
/// These responses are expected to be of the form `{"error": {"message": "some
/// message"}}`. If the format is correct, the message will be raised as an
/// error; otherwise an [invalidServerResponse] error will be raised.
void handleJsonError(http.BaseResponse response) {
  if (response is! http.Response) {
    // Not likely to be a common code path, but necessary.
    // See https://github.com/dart-lang/pub/pull/3590#discussion_r1012978108
    fail(log.red('Invalid server response'));
  }
  final errorMap = parseJsonResponse(response);
  final error = errorMap['error'];
  if (error is! Map ||
      !error.containsKey('message') ||
      error['message'] is! String) {
    invalidServerResponse(response);
  }
  final formattedMessage = log.red(
    sanitizeForTerminal(error['message'] as String),
  );
  fail('Message from server: $formattedMessage');
}

/// Handles an unsuccessful XML-formatted response from google cloud storage.
///
/// Assumes messages are of the form in
/// https://cloud.google.com/storage/docs/xml-api/reference-status
///
/// This is a poor person's XML parsing with regexps, but this should be
/// sufficient for the specified messages.
void handleGCSError(http.BaseResponse response) {
  if (response is http.Response) {
    final responseBody = response.body;
    if (responseBody.contains('<?xml')) {
      String? getTagText(String tag) {
        final result = RegExp('<$tag>(.*)</$tag>').firstMatch(responseBody)?[1];
        if (result == null) return null;
        return sanitizeForTerminal(result);
      }

      final code = getTagText('Code');
      // TODO(sigurdm): we could hard-code nice error messages for known codes.
      final message = getTagText('Message');
      // `Details` are not specified in the doc above, but have been observed in
      // actual responses.
      final details = getTagText('Details');
      if (code != null) {
        log.error('Server error code: ${sanitizeForTerminal(code)}');
      }
      if (message != null) {
        log.error('Server message: ${sanitizeForTerminal(message)}');
      }
      if (details != null) {
        log.error('Server details: ${sanitizeForTerminal(details)}');
      }
    }
  }
}

/// Parses a response body, assuming it's JSON-formatted.
///
/// Throws a user-friendly error if the response body is invalid JSON, or if
/// it's not a map.
Map parseJsonResponse(http.Response response) {
  Object? value;
  try {
    value = jsonDecode(response.body) as Object?;
  } on FormatException {
    invalidServerResponse(response);
  }
  if (value is! Map) invalidServerResponse(response);
  return value;
}

/// Throws an error describing an invalid response from the server.
Never invalidServerResponse(http.Response response) =>
    fail(log.red('Invalid server response:\n${response.body}'));

/// Exception thrown when an HTTP operation fails.
class PubHttpException implements Exception {
  final String message;
  final bool isIntermittent;

  PubHttpException(this.message, {this.isIntermittent = false});

  @override
  String toString() {
    return 'PubHttpException: $message';
  }
}

/// Exception thrown when an HTTP response is not Ok.
class PubHttpResponseException extends PubHttpException {
  final http.BaseResponse response;

  PubHttpResponseException(
    this.response, {
    String message = '',
    bool isIntermittent = false,
  }) : super(message, isIntermittent: isIntermittent);

  @override
  String toString() {
    var temp =
        'PubHttpResponseException: HTTP error ${response.statusCode} '
        '${response.reasonPhrase}';
    if (message != '') {
      temp += ': $message';
    }
    return temp;
  }
}

/// Whether [e] is one of a few HTTP-related exceptions that subclass
/// [IOException]. Can be used if your try-catch block contains various
/// operations in addition to HTTP calls and so a [IOException] instance check
/// would be too coarse.
bool isHttpIOException(Object e) {
  return e is HttpException ||
      e is TlsException ||
      e is SocketException ||
      e is WebSocketException;
}

/// Program-wide limiter for concurrent network requests.
final _httpPool = Pool(16);

/// Runs the provided function [fn] and returns the response.
///
/// If there is an HTTP-related exception, an intermittent HTTP error response,
/// or an async timeout, [fn] is run repeatedly until there is a successful
/// response or at most seven total attempts have been made. If all attempts
/// fail, the final exception is re-thrown.
///
/// Each attempt is run within a [Pool] configured with 16 maximum resources.
Future<T> retryForHttp<T>(String operation, FutureOr<T> Function() fn) async {
  return await retry(
    () async => await _httpPool.withResource(() async => await fn()),
    retryIf:
        (e) async =>
            (e is PubHttpException && e.isIntermittent) ||
            e is TimeoutException ||
            e is http.ClientException ||
            isHttpIOException(e),
    onRetry:
        (exception, attemptNumber) async =>
            log.io('Attempt #$attemptNumber for $operation'),
    maxAttempts: math.max(
      1, // Having less than 1 attempt doesn't make sense.
      int.tryParse(Platform.environment['PUB_MAX_HTTP_RETRIES'] ?? '') ?? 7,
    ),
  );
}

extension Throwing on http.BaseResponse {
  /// See https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html
  static const _redirectStatusCodes = [
    HttpStatus.movedPermanently,
    HttpStatus.movedTemporarily,
    HttpStatus.seeOther,
    HttpStatus.temporaryRedirect,
    HttpStatus.permanentRedirect,
  ];

  /// Throws [PubHttpResponseException], calls [fail], or does nothing depending
  /// on the status code.
  ///
  /// If the code is in the 200 range or if its a 300 range redirect code,
  /// nothing is done. If the code is 408, 429, or in the 500 range,
  /// [PubHttpResponseException] is thrown with "isIntermittent" set to `true`.
  /// Otherwise, [PubHttpResponseException] is thrown with "isIntermittent" set
  /// to `false`.
  void throwIfNotOk() {
    if (statusCode >= 200 && statusCode <= 299) {
      return;
    } else if (_redirectStatusCodes.contains(statusCode)) {
      return;
    } else if (statusCode == HttpStatus.notAcceptable &&
        request?.headers['Accept'] == pubApiHeaders['Accept']) {
      fail(
        'Pub ${sdk.version} is incompatible with the current version of '
        '${request?.url.host}.\n'
        'Upgrade pub to the latest version and try again.',
      );
    } else if (statusCode >= 500 ||
        statusCode == HttpStatus.requestTimeout ||
        statusCode == HttpStatus.tooManyRequests) {
      // Throw if the response indicates a server error or an intermittent
      // client error, but mark it as intermittent so it can be retried.
      throw PubHttpResponseException(this, isIntermittent: true);
    } else {
      // Throw for all other status codes.
      throw PubHttpResponseException(this);
    }
  }
}

extension RequestSending on http.Client {
  /// Sends an HTTP request, reads the whole response body, validates the
  /// response headers, and if validation is successful, and returns it.
  ///
  /// The send method on [http.Client], which returns a [http.StreamedResponse],
  /// is the only method that accepts a request object. This method can be used
  /// when you need to send a request object but want a regular response object.
  ///
  /// If false is passed for [throwIfNotOk], the response will not be validated.
  /// See [http.BaseResponse] extension for validation details.
  Future<http.Response> fetch(
    http.BaseRequest request, {
    bool throwIfNotOk = true,
  }) async {
    final streamedResponse = await send(request);
    final response = await http.Response.fromStream(streamedResponse);
    if (throwIfNotOk) {
      response.throwIfNotOk();
    }
    return response;
  }

  /// Sends an HTTP request, validates the response headers, and if validation
  /// is successful, returns a [http.StreamedResponse].
  ///
  /// If false is passed for [throwIfNotOk], the response will not be validated.
  /// See [Throwing.throwIfNotOk] extension for validation details.
  Future<http.StreamedResponse> fetchAsStream(
    http.BaseRequest request, {
    bool throwIfNotOk = true,
  }) async {
    final streamedResponse = await send(request);
    if (throwIfNotOk) {
      streamedResponse.throwIfNotOk();
    }
    return streamedResponse;
  }
}

/// Thrown by [_PubHttpClient.send] if the client was closed while the request
/// was being processed. Notably it doesn't implement [http.ClientException],
/// and thus does not trigger a retry by [retryForHttp].
class _ClientClosedException implements Exception {
  @override
  String toString() => 'Request was made after http client was closed';
}

class _OverrideUrlRequest implements http.BaseRequest {
  @override
  final Uri url;

  final http.BaseRequest wrapped;

  _OverrideUrlRequest(this.url, this.wrapped);

  @override
  int? get contentLength => wrapped.contentLength;

  @override
  Map<String, String> get headers => wrapped.headers;

  @override
  bool get persistentConnection => wrapped.persistentConnection;

  @override
  bool get followRedirects => wrapped.followRedirects;
  @override
  set followRedirects(bool value) => wrapped.followRedirects = value;

  @override
  int get maxRedirects => wrapped.maxRedirects;

  @override
  set maxRedirects(int value) => wrapped.maxRedirects = value;

  @override
  String get method => wrapped.method;

  @override
  set contentLength(int? value) => wrapped.contentLength = value;

  @override
  http.ByteStream finalize() => wrapped.finalize();

  @override
  bool get finalized => wrapped.finalized;

  @override
  Future<http.StreamedResponse> send() {
    throw UnimplementedError();
  }

  @override
  set persistentConnection(bool value) => wrapped.persistentConnection = value;
}
