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

part of "dart:io";

// TODO(bkonyi): refactor into io_resource_info.dart
const int _versionMajor = 4;
const int _versionMinor = 0;

const String _tcpSocket = 'tcp';
const String _udpSocket = 'udp';

/// Creates a Map conforming to the `HttpProfileRequest` type defined in the
/// dart:io service extension spec from an element of dart:developer's
/// `_developerProfilingData`.
Map<String, Object?> _createHttpProfileRequestFromProfileMap(
  Map<String, dynamic> requestProfile, {
  required bool ref,
}) {
  final responseData = requestProfile['responseData'] as Map<String, dynamic>;

  return {
    'type': '${ref ? '@' : ''}HttpProfileRequest',
    'id': requestProfile['id']!,
    'isolateId': requestProfile['isolateId']!,
    'method': requestProfile['requestMethod']!,
    'uri': requestProfile['requestUri']!,
    'events': requestProfile['events']!,
    'startTime': requestProfile['requestStartTimestamp']!,
    if (requestProfile['requestEndTimestamp'] != null)
      'endTime': requestProfile['requestEndTimestamp'],
    'request': requestProfile['requestData']!,
    'response': responseData,
    if (!ref && requestProfile['requestEndTimestamp'] != null)
      'requestBody': requestProfile['requestBodyBytes']!,
    if (!ref && responseData['endTime'] != null)
      'responseBody': requestProfile['responseBodyBytes']!,
  };
}

@pragma('vm:entry-point', !bool.fromEnvironment("dart.vm.product"))
abstract class _NetworkProfiling {
  // Http relative RPCs
  static const _kHttpEnableTimelineLogging =
      'ext.dart.io.httpEnableTimelineLogging';
  static const _kGetHttpProfileRPC = 'ext.dart.io.getHttpProfile';
  static const _kGetHttpProfileRequestRPC = 'ext.dart.io.getHttpProfileRequest';
  static const _kClearHttpProfileRPC = 'ext.dart.io.clearHttpProfile';
  // Socket relative RPCs
  static const _kClearSocketProfileRPC = 'ext.dart.io.clearSocketProfile';
  static const _kGetSocketProfileRPC = 'ext.dart.io.getSocketProfile';
  static const _kSocketProfilingEnabledRPC =
      'ext.dart.io.socketProfilingEnabled';

  // TODO(zichangguo): This version number represents the version of service
  // extension of dart:io. Consider moving this out of web profiler class,
  // if more methods added to dart:io,
  static const _kGetVersionRPC = 'ext.dart.io.getVersion';

  @pragma('vm:entry-point', !bool.fromEnvironment("dart.vm.product"))
  static void _registerServiceExtension() {
    registerExtension(_kHttpEnableTimelineLogging, _serviceExtensionHandler);
    registerExtension(_kGetSocketProfileRPC, _serviceExtensionHandler);
    registerExtension(_kSocketProfilingEnabledRPC, _serviceExtensionHandler);
    registerExtension(_kClearSocketProfileRPC, _serviceExtensionHandler);
    registerExtension(_kGetVersionRPC, _serviceExtensionHandler);
    registerExtension(_kGetHttpProfileRPC, _serviceExtensionHandler);
    registerExtension(_kGetHttpProfileRequestRPC, _serviceExtensionHandler);
    registerExtension(_kClearHttpProfileRPC, _serviceExtensionHandler);
  }

  // Note this function only returns a `Future` because that is required by the
  // signature of `registerExtension`. We might be able to change the signature
  // of ServiceExtensionHandler to use `FutureOr` instead of `Future`.
  static Future<ServiceExtensionResponse> _serviceExtensionHandler(
    String method,
    Map<String, String> parameters,
  ) async {
    try {
      String responseJson;
      switch (method) {
        case _kHttpEnableTimelineLogging:
          if (parameters.containsKey('enabled')) {
            _setHttpEnableTimelineLogging(parameters);
          }
          responseJson = _getHttpEnableTimelineLogging();
          break;
        case _kGetHttpProfileRPC:
          final updatedSince = parameters.containsKey('updatedSince')
              ? int.tryParse(parameters['updatedSince']!)
              : null;
          responseJson = json.encode({
            'type': 'HttpProfile',
            'timestamp': DateTime.now().microsecondsSinceEpoch,
            'requests': [
              ...HttpProfiler.serializeHttpProfileRequests(updatedSince),
              ...getHttpClientProfilingData()
                  .where(
                    (final Map<String, dynamic> p) =>
                        updatedSince == null ||
                        (p['_lastUpdateTime'] as int) >= updatedSince,
                  )
                  .map(
                    (p) =>
                        _createHttpProfileRequestFromProfileMap(p, ref: true),
                  ),
            ],
          });
          break;
        case _kGetHttpProfileRequestRPC:
          responseJson = _getHttpProfileRequest(parameters);
          break;
        case _kClearHttpProfileRPC:
          HttpProfiler.clear();
          responseJson = _success();
          break;
        case _kGetSocketProfileRPC:
          responseJson = _SocketProfile.toJson();
          break;
        case _kSocketProfilingEnabledRPC:
          responseJson = _socketProfilingEnabled(parameters);
          break;
        case _kClearSocketProfileRPC:
          responseJson = _SocketProfile.clear();
          break;
        case _kGetVersionRPC:
          responseJson = getVersion();
          break;
        default:
          return ServiceExtensionResponse.error(
            ServiceExtensionResponse.extensionError,
            'Method $method does not exist',
          );
      }
      return ServiceExtensionResponse.result(responseJson);
    } catch (errorMessage) {
      return ServiceExtensionResponse.error(
        ServiceExtensionResponse.invalidParams,
        errorMessage.toString(),
      );
    }
  }

  static String getVersion() => json.encode({
    'type': 'Version',
    'major': _versionMajor,
    'minor': _versionMinor,
  });
}

String _success() => json.encode({'type': 'Success'});

String _invalidArgument(String argument, dynamic value) =>
    "Value for parameter '$argument' is not valid: $value";

String _missingArgument(String argument) => "Parameter '$argument' is required";

String _getHttpEnableTimelineLogging() => json.encode({
  'type': 'HttpTimelineLoggingState',
  'enabled': HttpClient.enableTimelineLogging,
});

String _setHttpEnableTimelineLogging(Map<String, String> parameters) {
  const String kEnabled = 'enabled';
  if (!parameters.containsKey(kEnabled)) {
    throw _missingArgument(kEnabled);
  }
  final enable = parameters[kEnabled]!.toLowerCase();
  if (enable != 'true' && enable != 'false') {
    throw _invalidArgument(kEnabled, enable);
  }
  HttpClient.enableTimelineLogging = enable == 'true';
  return _success();
}

String _getHttpProfileRequest(Map<String, String> parameters) {
  final id = parameters['id'];
  if (id == null) {
    throw _missingArgument('id');
  }
  final Map<String, Object?>? request;
  if (id.startsWith('from_package/')) {
    final profileMap = getHttpClientProfilingData().elementAtOrNull(
      int.parse(id.substring('from_package/'.length)) - 1,
    );
    request = profileMap == null
        ? null
        : _createHttpProfileRequestFromProfileMap(profileMap, ref: false);
  } else {
    request = HttpProfiler.getHttpProfileRequest(id)?.toJson(ref: false);
  }

  if (request == null) {
    throw "Unable to find request with id: '$id'";
  }
  return json.encode(request);
}

String _socketProfilingEnabled(Map<String, String> parameters) {
  const String kEnabled = 'enabled';
  if (parameters.containsKey(kEnabled)) {
    final enable = parameters[kEnabled]!.toLowerCase();
    if (enable != 'true' && enable != 'false') {
      throw _invalidArgument(kEnabled, enable);
    }
    enable == 'true' ? _SocketProfile.start() : _SocketProfile.pause();
  }
  return json.encode({
    'type': 'SocketProfilingState',
    'enabled': _SocketProfile.enableSocketProfiling,
  });
}

abstract class _SocketProfile {
  static const _kType = 'SocketProfile';
  static set enableSocketProfiling(bool enabled) {
    if (enabled != _enableSocketProfiling) {
      postEvent('SocketProfilingStateChange', {
        'isolateId': Service.getIsolateID(Isolate.current),
        'enabled': enabled,
      });
      _enableSocketProfiling = enabled;
    }
  }

  static bool get enableSocketProfiling => _enableSocketProfiling;

  static bool _enableSocketProfiling = false;
  static Map<String, _SocketStatistic> _idToSocketStatistic = {};

  static String toJson() => json.encode({
    'type': _kType,
    'sockets': _idToSocketStatistic.values.map((f) => f.toMap()).toList(),
  });

  static void collectNewSocket(
    int id,
    String type,
    InternetAddress addr,
    int port,
  ) {
    if (!_enableSocketProfiling) {
      return;
    }
    // TODO(srawlins): Assert that `_idToSocketStatistic` does not contain
    // `id.toString()`?
    final address =
        (addr.type == InternetAddress.anyIPv6 ||
            addr.type == InternetAddress.loopbackIPv6)
        ? '[${addr.address}]'
        : addr.address;
    _idToSocketStatistic[id.toString()] = _SocketStatistic(
      id.toString(),
      startTime: Timeline.now,
      socketType: type,
      address: address,
      port: port,
    );
  }

  static void collectStatistic(
    int id,
    _SocketProfileType type, [
    Object? object,
  ]) {
    final idKey = id.toString();
    if (!_enableSocketProfiling) {
      return;
    }
    // Skip any socket that started before `_enableSocketProfiling` was turned
    // on.
    final stats = _idToSocketStatistic[idKey];
    if (stats == null) return;
    switch (type) {
      case _SocketProfileType.endTime:
        stats.endTime = Timeline.now;
        break;
      case _SocketProfileType.readBytes:
        if (object == null) return;
        stats.readBytes += object as int;
        stats.lastReadTime = Timeline.now;
        break;
      case _SocketProfileType.writeBytes:
        if (object == null) return;
        stats.writeBytes += object as int;
        stats.lastWriteTime = Timeline.now;
        break;
      case _SocketProfileType.startTime:
      case _SocketProfileType.socketType:
      case _SocketProfileType.address:
      case _SocketProfileType.port:
        throw ArgumentError(
          'The "${type}" type can only be set on initialization',
        );
    }
  }

  static String start() {
    enableSocketProfiling = true;
    return _success();
  }

  static String pause() {
    enableSocketProfiling = false;
    return _success();
  }

  // clear the storage if _idToSocketStatistic has been initialized.
  static String clear() {
    _idToSocketStatistic.clear();
    return _success();
  }
}

/// The [_SocketProfileType] is used as a parameter for
/// [_SocketProfile.collectStatistic] to determine the type of statistic.
enum _SocketProfileType {
  startTime,
  endTime,
  address,
  port,
  socketType,
  readBytes,
  writeBytes,
}

/// Socket statistic
class _SocketStatistic {
  final String id;
  final int startTime;
  int? endTime;
  final String address;
  final int port;
  final String socketType;
  int readBytes = 0;
  int writeBytes = 0;
  int? lastWriteTime;
  int? lastReadTime;

  _SocketStatistic(
    this.id, {
    required this.startTime,
    required this.socketType,
    required this.address,
    required this.port,
  });

  Map<String, dynamic> toMap() {
    final map = <String, Object>{
      'id': id,
      'startTime': startTime,
      'address': address,
      'port': port,
      'socketType': socketType,
    };
    // TODO(srawlins): Replace with null-aware elements.
    _setIfNotNull(map, 'endTime', endTime);
    _setIfNotNull(map, 'readBytes', readBytes);
    _setIfNotNull(map, 'writeBytes', writeBytes);
    _setIfNotNull(map, 'lastWriteTime', lastWriteTime);
    _setIfNotNull(map, 'lastReadTime', lastReadTime);
    return map;
  }

  void _setIfNotNull(Map<String, dynamic> json, String key, Object? value) {
    if (value == null) return;
    json[key] = value;
  }
}
