// Copyright 2014 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.

part of reporting;

/// A generic usage even that does not involve custom dimensions.
///
/// If sending values for custom dimensions is required, extend this class as
/// below.
class UsageEvent {
  UsageEvent(this.category, this.parameter, {
    this.label,
    this.value,
    required this.flutterUsage,
  });

  final String category;
  final String parameter;
  final String? label;
  final int? value;
  final Usage flutterUsage;

  void send() {
    flutterUsage.sendEvent(category, parameter, label: label, value: value);
  }
}

/// A usage event related to hot reload/restart.
///
/// On a successful hot reload, we collect stats that help understand scale of
/// the update. For example, [syncedLibraryCount]/[finalLibraryCount] indicates
/// how many libraries were affected by the hot reload request. Relation of
/// [invalidatedSourcesCount] to [syncedLibraryCount] should help understand
/// sync/transfer "overhead" of updating this number of source files.
class HotEvent extends UsageEvent {
  HotEvent(String parameter, {
    required this.targetPlatform,
    required this.sdkName,
    required this.emulator,
    required this.fullRestart,
    required this.fastReassemble,
    this.reason,
    this.finalLibraryCount,
    this.syncedLibraryCount,
    this.syncedClassesCount,
    this.syncedProceduresCount,
    this.syncedBytes,
    this.invalidatedSourcesCount,
    this.transferTimeInMs,
    this.overallTimeInMs,
    this.compileTimeInMs,
    this.findInvalidatedTimeInMs,
    this.scannedSourcesCount,
    this.reassembleTimeInMs,
    this.reloadVMTimeInMs,
  }) : super('hot', parameter, flutterUsage: globals.flutterUsage);

  final String? reason;
  final String targetPlatform;
  final String sdkName;
  final bool emulator;
  final bool fullRestart;
  final bool fastReassemble;
  final int? finalLibraryCount;
  final int? syncedLibraryCount;
  final int? syncedClassesCount;
  final int? syncedProceduresCount;
  final int? syncedBytes;
  final int? invalidatedSourcesCount;
  final int? transferTimeInMs;
  final int? overallTimeInMs;
  final int? compileTimeInMs;
  final int? findInvalidatedTimeInMs;
  final int? scannedSourcesCount;
  final int? reassembleTimeInMs;
  final int? reloadVMTimeInMs;

  @override
  void send() {
    final CustomDimensions parameters = CustomDimensions(
      hotEventTargetPlatform: targetPlatform,
      hotEventSdkName: sdkName,
      hotEventEmulator: emulator,
      hotEventFullRestart: fullRestart,
      hotEventReason: reason,
      hotEventFinalLibraryCount: finalLibraryCount,
      hotEventSyncedLibraryCount: syncedLibraryCount,
      hotEventSyncedClassesCount: syncedClassesCount,
      hotEventSyncedProceduresCount: syncedProceduresCount,
      hotEventSyncedBytes: syncedBytes,
      hotEventInvalidatedSourcesCount: invalidatedSourcesCount,
      hotEventTransferTimeInMs: transferTimeInMs,
      hotEventOverallTimeInMs: overallTimeInMs,
      fastReassemble: fastReassemble,
      hotEventCompileTimeInMs: compileTimeInMs,
      hotEventFindInvalidatedTimeInMs: findInvalidatedTimeInMs,
      hotEventScannedSourcesCount: scannedSourcesCount,
      hotEventReassembleTimeInMs: reassembleTimeInMs,
      hotEventReloadVMTimeInMs: reloadVMTimeInMs,
    );
    flutterUsage.sendEvent(category, parameter, parameters: parameters);
  }
}

/// An event that reports the result of a [DoctorValidator]
class DoctorResultEvent extends UsageEvent {
  DoctorResultEvent({
    required this.validator,
    required this.result,
    Usage? flutterUsage,
  }) : super(
    'doctor-result',
    '${validator.runtimeType}',
    label: result.typeStr,
    flutterUsage: flutterUsage ?? globals.flutterUsage,
  );

  final DoctorValidator validator;
  final ValidationResult result;

  @override
  void send() {
    if (validator is! GroupedValidator) {
      flutterUsage.sendEvent(category, parameter, label: label);
      return;
    }
    final GroupedValidator group = validator as GroupedValidator;
    // The validator crashed.
    if (group.subResults.isEmpty) {
      flutterUsage.sendEvent(category, parameter, label: label);
      return;
    }
    for (int i = 0; i < group.subValidators.length; i++) {
      final DoctorValidator v = group.subValidators[i];
      final ValidationResult r = group.subResults[i];
      DoctorResultEvent(validator: v, result: r, flutterUsage: flutterUsage).send();
    }
  }
}

/// An event that reports on the result of a pub invocation.
class PubResultEvent extends UsageEvent {
  PubResultEvent({
    required String context,
    required String result,
    required Usage usage,
  }) : super('pub-result', context, label: result, flutterUsage: usage);
}

/// An event that reports something about a build.
class BuildEvent extends UsageEvent {
  BuildEvent(String label, {
    String? command,
    String? settings,
    String? eventError,
    required Usage flutterUsage,
    required String type,
  }) : _command = command,
  _settings = settings,
  _eventError = eventError,
      super(
    // category
    'build',
    // parameter
    type,
    label: label,
    flutterUsage: flutterUsage,
  );

  final String? _command;
  final String? _settings;
  final String? _eventError;

  @override
  void send() {
    final CustomDimensions parameters = CustomDimensions(
      buildEventCommand: _command,
      buildEventSettings: _settings,
      buildEventError: _eventError,
    );
    flutterUsage.sendEvent(
      category,
      parameter,
      label: label,
      parameters: parameters,
    );
  }
}

/// An event that reports the result of a top-level command.
class CommandResultEvent extends UsageEvent {
  CommandResultEvent(super.commandPath, super.result)
      : assert(commandPath != null),
        assert(result != null),
        super(flutterUsage: globals.flutterUsage);

  @override
  void send() {
    // An event for the command result.
    flutterUsage.sendEvent(
      'tool-command-result',
      category,
      label: parameter,
    );

    // A separate event for the memory highwater mark. This is a separate event
    // so that we can get the command result even if trying to grab maxRss
    // throws an exception.
    try {
      final int maxRss = globals.processInfo.maxRss;
      flutterUsage.sendEvent(
        'tool-command-max-rss',
        category,
        label: parameter,
        value: maxRss,
      );
    } on Exception catch (error) {
      // If grabbing the maxRss fails for some reason, just don't send an event.
      globals.printTrace('Querying maxRss failed with error: $error');
    }
  }
}

/// An event that reports on changes in the configuration of analytics.
class AnalyticsConfigEvent extends UsageEvent {
  AnalyticsConfigEvent({
    /// Whether analytics reporting is being enabled (true) or disabled (false).
    required bool enabled,
  }) : super(
    'analytics',
    'enabled',
    label: enabled ? 'true' : 'false',
    flutterUsage: globals.flutterUsage,
  );
}

/// An event that reports when the code size measurement is run via `--analyze-size`.
class CodeSizeEvent extends UsageEvent {
  CodeSizeEvent(String platform, {
    required Usage flutterUsage,
  }) : super(
    'code-size-analysis',
    platform,
    flutterUsage: flutterUsage
  );
}

/// An event for tracking the usage of specific error handling fallbacks.
class ErrorHandlingEvent extends UsageEvent {
  ErrorHandlingEvent(String parameter) : super('error-handling', parameter, flutterUsage: globals.flutterUsage);
}

/// Emit various null safety analytic events.
///
/// 1. The current null safety runtime mode.
/// 2. The number of packages that are migrated, along with the total number of packages
/// 3. The main packages language version.
class NullSafetyAnalysisEvent implements UsageEvent {
  NullSafetyAnalysisEvent(
    this.packageConfig,
    this.nullSafetyMode,
    this.currentPackage,
    this.flutterUsage,
  );

  /// The category for analytics events related to null safety.
  static const String kNullSafetyCategory = 'null-safety';

  final PackageConfig packageConfig;
  final NullSafetyMode nullSafetyMode;
  final String currentPackage;
  @override
  final Usage flutterUsage;

  @override
  void send() {
    if (packageConfig.packages.isEmpty) {
      return;
    }
    int migrated = 0;
    LanguageVersion? languageVersion;
    for (final Package package in packageConfig.packages) {
      final LanguageVersion? packageLanguageVersion = package.languageVersion;
      if (package.name == currentPackage) {
        languageVersion = packageLanguageVersion;
      }
      if (packageLanguageVersion != null &&
          packageLanguageVersion.major >= nullSafeVersion.major &&
          packageLanguageVersion.minor >= nullSafeVersion.minor) {
        migrated += 1;
      }
    }
    flutterUsage.sendEvent(kNullSafetyCategory, 'runtime-mode', label: nullSafetyMode.toString());
    flutterUsage.sendEvent(kNullSafetyCategory, 'stats', parameters: CustomDimensions(
      nullSafeMigratedLibraries: migrated,
      nullSafeTotalLibraries: packageConfig.packages.length,
    ));
    if (languageVersion != null) {
      final String formattedVersion = '${languageVersion.major}.${languageVersion.minor}';
      flutterUsage.sendEvent(kNullSafetyCategory, 'language-version', label: formattedVersion);
    }
  }

  @override
  String get category => kNullSafetyCategory;

  @override
  String get label => throw UnsupportedError('');

  @override
  String get parameter => throw UnsupportedError('');

  @override
  int get value => throw UnsupportedError('');
}
