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

import 'dart:io';

import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
// ignore: implementation_imports
import 'package:usage/src/usage_impl.dart';
// ignore: implementation_imports
import 'package:usage/src/usage_impl_io.dart';
// ignore: implementation_imports
import 'package:usage/src/usage_impl_io.dart' as usage_io show getDartVersion;
import 'package:usage/usage.dart';
import 'package:usage/usage_io.dart';

export 'package:usage/usage.dart' show Analytics;

// TODO(devoncarew): Don't show the UI until we're ready to ship.
final bool showAnalyticsUI = false;

final String _dartDirectoryName = '.dart';
final String _settingsFileName = 'analytics.json';

/// Dart SDK tools with analytics should display this notice.
///
/// In addition, they should support displaying the analytics' status, and have
/// a flag to toggle analytics. This may look something like:
///
/// `Analytics are currently enabled (and can be disabled with --no-analytics).`
final String analyticsNotice =
    "Dart SDK tools anonymously report feature usage statistics and basic crash\n"
    "reports to help improve Dart tools over time. See Google's privacy policy:\n"
    "https://www.google.com/intl/en/policies/privacy/.";

/// Return a customized message for command-line tools to display about the
/// state of analytics, and how users can enabled or disable analytics.
///
/// An example return value might be `'Analytics are currently enabled (and can
/// be disabled with --no-analytics).'`
String createAnalyticsStatusMessage(
  bool enabled, {
  String command = 'analytics',
}) {
  String currentState = enabled ? 'enabled' : 'disabled';
  String toggleState = enabled ? 'disabled' : 'enabled';
  String commandToggle = enabled ? 'no-$command' : command;

  return 'Analytics are currently $currentState '
      '(and can be $toggleState with --$commandToggle).';
}

/// Create an [Analytics] instance with the given trackingID and
/// applicationName.
///
/// This analytics instance will share a common enablement state with the rest
/// of the Dart SDK tools.
Analytics createAnalyticsInstance(
  String trackingId,
  String applicationName, {
  bool disableForSession = false,
  bool forceEnabled = false,
}) {
  final dir = getDartStorageDirectory();
  if (dir == null) {
    // Some systems don't support user home directories; for those, fail
    // gracefully by returning a disabled analytics object.
    return _DisabledAnalytics(trackingId, applicationName);
  }

  if (!dir.existsSync()) {
    try {
      dir.createSync();
    } catch (e) {
      // If we can't create the directory for the analytics settings, fail
      // gracefully by returning a disabled analytics object.
      return _DisabledAnalytics(trackingId, applicationName);
    }
  }

  File settingsFile = File(path.join(dir.path, _settingsFileName));
  return _TelemetryAnalytics(
    trackingId,
    applicationName,
    getDartVersion(),
    settingsFile,
    disableForSession: disableForSession,
    forceEnabled: forceEnabled,
  );
}

/// The directory used to store the analytics settings file.
///
/// Typically, the directory is `~/.dart/` (and the settings file is
/// `analytics.json`).
///
/// This can return null under some conditions, including when the user's home
/// directory does not exist.
@visibleForTesting
Directory? getDartStorageDirectory() {
  Directory homeDirectory = Directory(userHomeDir());
  if (!homeDirectory.existsSync()) return null;

  return Directory(path.join(homeDirectory.path, _dartDirectoryName));
}

/// Return the version of the Dart SDK.
String getDartVersion() => usage_io.getDartVersion();

class _TelemetryAnalytics extends AnalyticsImpl {
  final bool disableForSession;
  final bool forceEnabled;

  _TelemetryAnalytics(
    String trackingId,
    String applicationName,
    String applicationVersion,
    File settingsFile, {
    required this.disableForSession,
    required this.forceEnabled,
  }) : super(
          trackingId,
          IOPersistentProperties.fromFile(settingsFile),
          IOPostHandler(),
          applicationName: applicationName,
          applicationVersion: applicationVersion,
        ) {
    final locale = getPlatformLocale();
    if (locale != null) {
      setSessionValue('ul', locale);
    }
  }

  @override
  bool get enabled {
    if (disableForSession || isRunningOnBot()) {
      return false;
    }

    // This is only used in special cases.
    if (forceEnabled) {
      return true;
    }

    // If there's no explicit setting (enabled or disabled) then we don't send.
    return (properties['enabled'] as bool?) ?? false;
  }
}

class _DisabledAnalytics extends AnalyticsMock {
  @override
  final String trackingId;
  @override
  final String applicationName;

  _DisabledAnalytics(this.trackingId, this.applicationName);

  @override
  bool get enabled => false;
}

/// Detect whether we're running on a bot or in a continuous testing
/// environment.
///
/// We should periodically keep this code up to date with:
/// https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/base/bot_detector.dart#L30
/// and
/// https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/reporting/usage.dart#L200.
bool isRunningOnBot() {
  final Map<String, String> env = Platform.environment;

  if (
      // Explicitly stated to not be a bot.
      env['BOT'] == 'false'
          // Set by the IDEs to the IDE name, so a strong signal that this is not a bot.
          ||
          env.containsKey('FLUTTER_HOST')
          // When set, GA logs to a local file (normally for tests) so we don't need to filter.
          ||
          env.containsKey('FLUTTER_ANALYTICS_LOG_FILE')) {
    return false;
  }

  return env.containsKey('BOT')
      // https://docs.travis-ci.com/user/environment-variables/
      // Example .travis.yml file: https://github.com/flutter/devtools/blob/master/.travis.yml
      ||
      env['TRAVIS'] == 'true' ||
      env['CONTINUOUS_INTEGRATION'] == 'true' ||
      env.containsKey('CI') // Travis and AppVeyor

      // https://www.appveyor.com/docs/environment-variables/
      ||
      env.containsKey('APPVEYOR')

      // https://cirrus-ci.org/guide/writing-tasks/#environment-variables
      ||
      env.containsKey('CIRRUS_CI')

      // https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
      ||
      (env.containsKey('AWS_REGION') && env.containsKey('CODEBUILD_INITIATOR'))

      // https://wiki.jenkins.io/display/JENKINS/Building+a+software+project#Buildingasoftwareproject-belowJenkinsSetEnvironmentVariables
      ||
      env.containsKey('JENKINS_URL')

      // https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
      ||
      env.containsKey('GITHUB_ACTIONS')

      // Properties on Flutter's Chrome Infra bots.
      ||
      env['CHROME_HEADLESS'] == '1' ||
      env.containsKey('BUILDBOT_BUILDERNAME') ||
      env.containsKey('SWARMING_TASK_ID')

      // Property when running on borg.
      ||
      env.containsKey('BORG_ALLOC_DIR');

  // TODO(jwren): Azure detection -- each call for this detection requires an
  //  http connection, the flutter cli tool captures the result on the first
  //  run, we should consider the same caching here.
}
