// 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.dart';

const String _kFlutterUA = 'UA-67589403-6';

abstract class Usage {
  /// Create a new Usage instance; [versionOverride], [configDirOverride], and
  /// [logFile] are used for testing.
  factory Usage({
    String settingsName = 'flutter',
    String? versionOverride,
    String? configDirOverride,
    String? logFile,
    AnalyticsFactory? analyticsIOFactory,
    FirstRunMessenger? firstRunMessenger,
    required bool runningOnBot,
  }) =>
      _DefaultUsage.initialize(
        settingsName: settingsName,
        versionOverride: versionOverride,
        configDirOverride: configDirOverride,
        logFile: logFile,
        analyticsIOFactory: analyticsIOFactory,
        runningOnBot: runningOnBot,
        firstRunMessenger: firstRunMessenger,
      );

  /// Uses the global [Usage] instance to send a 'command' to analytics.
  static void command(String command, {
    CustomDimensions? parameters,
  }) => globals.flutterUsage.sendCommand(command, parameters: parameters);

  /// Whether analytics reporting should be suppressed.
  bool get suppressAnalytics;

  /// Suppress analytics for this session.
  set suppressAnalytics(bool value);

  /// Whether analytics reporting is enabled.
  bool get enabled;

  /// Enable or disable reporting analytics.
  set enabled(bool value);

  /// A stable randomly generated UUID used to deduplicate multiple identical
  /// reports coming from the same computer.
  String get clientId;

  /// Sends a 'command' to the underlying analytics implementation.
  ///
  /// Note that using [command] above is preferred to ensure that the parameter
  /// keys are well-defined in [CustomDimensions] above.
  void sendCommand(
    String command, {
    CustomDimensions? parameters,
  });

  /// Sends an 'event' to the underlying analytics implementation.
  ///
  /// Note that this method should not be used directly, instead see the
  /// event types defined in this directory in events.dart.
  @visibleForOverriding
  @visibleForTesting
  void sendEvent(
    String category,
    String parameter, {
    String? label,
    int? value,
    CustomDimensions? parameters,
  });

  /// Sends timing information to the underlying analytics implementation.
  void sendTiming(
    String category,
    String variableName,
    Duration duration, {
    String? label,
  });

  /// Sends an exception to the underlying analytics implementation.
  void sendException(dynamic exception);

  /// Fires whenever analytics data is sent over the network.
  @visibleForTesting
  Stream<Map<String, dynamic>> get onSend;

  /// Returns when the last analytics event has been sent, or after a fixed
  /// (short) delay, whichever is less.
  Future<void> ensureAnalyticsSent();

  /// Prints a welcome message that informs the tool user about the collection
  /// of anonymous usage information.
  void printWelcome();
}

typedef AnalyticsFactory = Analytics Function(
  String trackingId,
  String applicationName,
  String applicationVersion, {
  String analyticsUrl,
  Directory? documentDirectory,
});

Analytics _defaultAnalyticsIOFactory(
  String trackingId,
  String applicationName,
  String applicationVersion, {
  String? analyticsUrl,
  Directory? documentDirectory,
}) {
  return AnalyticsIO(
    trackingId,
    applicationName,
    applicationVersion,
    analyticsUrl: analyticsUrl,
    documentDirectory: documentDirectory,
  );
}

class _DefaultUsage implements Usage {
  _DefaultUsage._({
    required bool suppressAnalytics,
    required Analytics analytics,
    required this.firstRunMessenger,
    required SystemClock clock,
  })  : _suppressAnalytics = suppressAnalytics,
        _analytics = analytics,
        _clock = clock;

  static _DefaultUsage initialize({
    String settingsName = 'flutter',
    String? versionOverride,
    String? configDirOverride,
    String? logFile,
    AnalyticsFactory? analyticsIOFactory,
    required FirstRunMessenger? firstRunMessenger,
    required bool runningOnBot,
  }) {
    final FlutterVersion flutterVersion = globals.flutterVersion;
    final String version = versionOverride ?? flutterVersion.getVersionString(redactUnknownBranches: true);
    final bool suppressEnvFlag = globals.platform.environment['FLUTTER_SUPPRESS_ANALYTICS'] == 'true';
    final String? logFilePath = logFile ?? globals.platform.environment['FLUTTER_ANALYTICS_LOG_FILE'];
    final bool usingLogFile = logFilePath != null && logFilePath.isNotEmpty;

    final AnalyticsFactory analyticsFactory = analyticsIOFactory ?? _defaultAnalyticsIOFactory;
    bool suppressAnalytics = false;
    bool skipAnalyticsSessionSetup = false;
    Analytics? setupAnalytics;
    if (// To support testing, only allow other signals to suppress analytics
        // when analytics are not being shunted to a file.
        !usingLogFile && (
        // Ignore local user branches.
        version.startsWith('[user-branch]') ||
        // Many CI systems don't do a full git checkout.
        version.endsWith('/unknown') ||
        // Ignore bots.
        runningOnBot ||
        // Ignore when suppressed by FLUTTER_SUPPRESS_ANALYTICS.
        suppressEnvFlag
    )) {
      // If we think we're running on a CI system, suppress sending analytics.
      suppressAnalytics = true;
      setupAnalytics = AnalyticsMock();
      skipAnalyticsSessionSetup = true;
    }
    if (usingLogFile) {
      setupAnalytics ??= LogToFileAnalytics(logFilePath);
    } else {
      try {
        ErrorHandlingFileSystem.noExitOnFailure(() {
          setupAnalytics = analyticsFactory(
            _kFlutterUA,
            settingsName,
            version,
            documentDirectory: configDirOverride != null
                ? globals.fs.directory(configDirOverride)
                : null,
          );
        });
      } on Exception catch (e) {
        globals.printTrace('Failed to initialize analytics reporting: $e');
        suppressAnalytics = true;
        setupAnalytics ??= AnalyticsMock();
        skipAnalyticsSessionSetup = true;
      }
    }

    final Analytics analytics = setupAnalytics!;
    if (!skipAnalyticsSessionSetup) {
      // Report a more detailed OS version string than package:usage does by default.
      analytics.setSessionValue(
        cdKey(CustomDimensionsEnum.sessionHostOsDetails),
        globals.os.name,
      );
      // Send the branch name as the "channel".
      analytics.setSessionValue(
        cdKey(CustomDimensionsEnum.sessionChannelName),
        flutterVersion.getBranchName(redactUnknownBranches: true),
      );
      // For each flutter experimental feature, record a session value in a comma
      // separated list.
      final String enabledFeatures = allFeatures
          .where((Feature feature) {
        final String? configSetting = feature.configSetting;
        return configSetting != null && globals.config.getValue(configSetting) == true;
      })
          .map((Feature feature) => feature.configSetting)
          .join(',');
      analytics.setSessionValue(
        cdKey(CustomDimensionsEnum.enabledFlutterFeatures),
        enabledFeatures,
      );

      // Record the host as the application installer ID - the context that flutter_tools is running in.
      if (globals.platform.environment.containsKey('FLUTTER_HOST')) {
        analytics.setSessionValue('aiid', globals.platform.environment['FLUTTER_HOST']);
      }
      analytics.analyticsOpt = AnalyticsOpt.optOut;
    }

    return _DefaultUsage._(
      suppressAnalytics: suppressAnalytics,
      analytics: analytics,
      firstRunMessenger: firstRunMessenger,
      clock: globals.systemClock,
    );
  }

  final Analytics _analytics;
  final FirstRunMessenger? firstRunMessenger;

  bool _printedWelcome = false;
  bool _suppressAnalytics = false;
  final SystemClock _clock;

  @override
  bool get suppressAnalytics => _suppressAnalytics || _analytics.firstRun;

  @override
  set suppressAnalytics(bool value) {
    _suppressAnalytics = value;
  }

  @override
  bool get enabled => _analytics.enabled;

  @override
  set enabled(bool value) {
    _analytics.enabled = value;
  }

  @override
  String get clientId => _analytics.clientId;

  @override
  void sendCommand(String command, { CustomDimensions? parameters }) {
    if (suppressAnalytics) {
      return;
    }

    _analytics.sendScreenView(
      command,
      parameters: CustomDimensions(localTime: formatDateTime(_clock.now()))
          .merge(parameters)
          .toMap(),
    );
  }

  @override
  void sendEvent(
    String category,
    String parameter, {
    String? label,
    int? value,
    CustomDimensions? parameters,
  }) {
    if (suppressAnalytics) {
      return;
    }

    _analytics.sendEvent(
      category,
      parameter,
      label: label,
      value: value,
      parameters: CustomDimensions(localTime: formatDateTime(_clock.now()))
          .merge(parameters)
          .toMap(),
    );
  }

  @override
  void sendTiming(
    String category,
    String variableName,
    Duration duration, {
    String? label,
  }) {
    if (suppressAnalytics) {
      return;
    }
    _analytics.sendTiming(
      variableName,
      duration.inMilliseconds,
      category: category,
      label: label,
    );
  }

  @override
  void sendException(dynamic exception) {
    if (suppressAnalytics) {
      return;
    }
    _analytics.sendException(exception.runtimeType.toString());
  }

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

  @override
  Future<void> ensureAnalyticsSent() async {
    // TODO(devoncarew): This may delay tool exit and could cause some analytics
    // events to not be reported. Perhaps we could send the analytics pings
    // out-of-process from flutter_tools?
    await _analytics.waitForLastPing(timeout: const Duration(milliseconds: 250));
  }

  @override
  void printWelcome() {
    // Only print once per run.
    if (_printedWelcome) {
      return;
    }
    // Display the welcome message if this is the first run of the tool or if
    // the license terms have changed since it was last displayed.
    final FirstRunMessenger? messenger = firstRunMessenger;
    if (messenger != null && messenger.shouldDisplayLicenseTerms()) {
      globals.printStatus('');
      globals.printStatus(messenger.licenseTerms, emphasis: true);
      _printedWelcome = true;
      messenger.confirmLicenseTermsDisplayed();
    }
  }
}

// An Analytics mock that logs to file. Unimplemented methods goes to stdout.
// But stdout can't be used for testing since wrapper scripts like
// xcode_backend.sh etc manipulates them.
class LogToFileAnalytics extends AnalyticsMock {
  LogToFileAnalytics(String logFilePath) :
    logFile = globals.fs.file(logFilePath)..createSync(recursive: true),
    super(true);

  final File logFile;
  final Map<String, String> _sessionValues = <String, String>{};

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

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

  @override
  Future<void> sendScreenView(String viewName, {
    Map<String, String>? parameters,
  }) {
    if (!enabled) {
      return Future<void>.value();
    }
    parameters ??= <String, String>{};
    parameters['viewName'] = viewName;
    parameters.addAll(_sessionValues);
    _sendController.add(parameters);
    logFile.writeAsStringSync('screenView $parameters\n', mode: FileMode.append);
    return Future<void>.value();
  }

  @override
  Future<void> sendEvent(String category, String action,
      {String? label, int? value, Map<String, String>? parameters}) {
    if (!enabled) {
      return Future<void>.value();
    }
    parameters ??= <String, String>{};
    parameters['category'] = category;
    parameters['action'] = action;
    _sendController.add(parameters);
    logFile.writeAsStringSync('event $parameters\n', mode: FileMode.append);
    return Future<void>.value();
  }

  @override
  Future<void> sendTiming(String variableName, int time,
      {String? category, String? label}) {
    if (!enabled) {
      return Future<void>.value();
    }
    final Map<String, String> parameters = <String, String>{
      'variableName': variableName,
      'time': '$time',
      if (category != null) 'category': category,
      if (label != null) 'label': label,
    };
    _sendController.add(parameters);
    logFile.writeAsStringSync('timing $parameters\n', mode: FileMode.append);
    return Future<void>.value();
  }

  @override
  void setSessionValue(String param, dynamic value) {
    _sessionValues[param] = value.toString();
  }
}


/// Create a testing Usage instance.
///
/// All sent events, exceptions, timings, and pages are
/// buffered on the object and can be inspected later.
@visibleForTesting
class TestUsage implements Usage {
  final List<TestUsageCommand> commands = <TestUsageCommand>[];
  final List<TestUsageEvent> events = <TestUsageEvent>[];
  final List<dynamic> exceptions = <dynamic>[];
  final List<TestTimingEvent> timings = <TestTimingEvent>[];
  int ensureAnalyticsSentCalls = 0;

  @override
  bool enabled = true;

  @override
  bool suppressAnalytics = false;

  @override
  String get clientId => 'test-client';

  @override
  Future<void> ensureAnalyticsSent() async {
    ensureAnalyticsSentCalls++;
  }

  @override
  Stream<Map<String, dynamic>> get onSend => throw UnimplementedError();

  @override
  void printWelcome() { }

  @override
  void sendCommand(String command, {CustomDimensions? parameters}) {
    commands.add(TestUsageCommand(command, parameters: parameters));
  }

  @override
  void sendEvent(String category, String parameter, {String? label, int? value, CustomDimensions? parameters}) {
    events.add(TestUsageEvent(category, parameter, label: label, value: value, parameters: parameters));
  }

  @override
  void sendException(dynamic exception) {
    exceptions.add(exception);
  }

  @override
  void sendTiming(String category, String variableName, Duration duration, {String? label}) {
    timings.add(TestTimingEvent(category, variableName, duration, label: label));
  }
}

@visibleForTesting
@immutable
class TestUsageCommand {
  const TestUsageCommand(this.command, {this.parameters});

  final String command;
  final CustomDimensions? parameters;

  @override
  bool operator ==(Object other) {
    return other is TestUsageCommand &&
      other.command == command &&
      other.parameters == parameters;
  }

  @override
  int get hashCode => Object.hash(command, parameters);

  @override
  String toString() => 'TestUsageCommand($command, parameters:$parameters)';
}

@visibleForTesting
@immutable
class TestUsageEvent {
  const TestUsageEvent(this.category, this.parameter, {this.label, this.value, this.parameters});

  final String category;
  final String parameter;
  final String? label;
  final int? value;
  final CustomDimensions? parameters;

  @override
  bool operator ==(Object other) {
    return other is TestUsageEvent &&
      other.category == category &&
      other.parameter == parameter &&
      other.label == label &&
      other.value == value &&
      other.parameters == parameters;
  }

  @override
  int get hashCode => Object.hash(category, parameter, label, value, parameters);

  @override
  String toString() => 'TestUsageEvent($category, $parameter, label:$label, value:$value, parameters:$parameters)';
}

@visibleForTesting
@immutable
class TestTimingEvent {
  const TestTimingEvent(this.category, this.variableName, this.duration, {this.label});

  final String category;
  final String variableName;
  final Duration duration;
  final String? label;

  @override
  bool operator ==(Object other) {
    return other is TestTimingEvent &&
      other.category == category &&
      other.variableName == variableName &&
      other.duration == duration &&
      other.label == label;
  }

  @override
  int get hashCode => Object.hash(category, variableName, duration, label);

  @override
  String toString() => 'TestTimingEvent($category, $variableName, $duration, label:$label)';
}

bool _mapsEqual(Map<dynamic, dynamic>? a, Map<dynamic, dynamic>? b) {
  if (a == b) {
    return true;
  }
  if (a == null || b == null) {
    return false;
  }
  if (a.length != b.length) {
    return false;
  }

  for (final dynamic k in a.keys) {
    final dynamic bValue = b[k];
    if (bValue == null && !b.containsKey(k)) {
      return false;
    }
    if (bValue != a[k]) {
      return false;
    }
  }

  return true;
}
