// 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;

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;
}
