// Copyright (c) 2014, 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:async';
import 'dart:convert' show JsonEncoder, jsonDecode;
import 'dart:io';

import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

import 'usage_impl.dart';

/// An interface to a Google Analytics session, suitable for use in command-line
/// applications.
///
/// [analyticsUrl] is an optional replacement for the default Google Analytics
/// URL (`https://www.google-analytics.com/collect`).
///
/// `trackingId`, `applicationName`, and `applicationVersion` values should be supplied.
/// `analyticsUrl` is optional, and lets user's substitute their own analytics URL for
/// the default.
///
/// `documentDirectory` is where the analytics settings are stored. It
/// defaults to the user home directory. For regular `dart:io` apps this doesn't need to
/// be supplied. For Flutter applications, you should pass in a value like
/// `PathProvider.getApplicationDocumentsDirectory()`.
///
/// [batchingDelay] is used to control batching behaviour. Events will be sent
/// batches of 20 after the duration is over from when the first message was
/// sent.
///
/// If [batchingDelay] is `Duration()` messages will be sent when control
/// returns to the event loop.
///
/// Batched messages are sent in batches of up to 20 messages. They will be sent
/// to [analyticsBatchingUrl] defaulting to
/// `https://www.google-analytics.com/batch`.
class AnalyticsIO extends AnalyticsImpl {
  AnalyticsIO(
    String trackingId,
    String applicationName,
    String applicationVersion, {
    String? analyticsUrl,
    String? analyticsBatchingUrl,
    Directory? documentDirectory,
    HttpClient? client,
    Duration? batchingDelay,
  }) : super(
          trackingId,
          IOPersistentProperties(applicationName,
              documentDirPath: documentDirectory?.path),
          IOPostHandler(client: client),
          applicationName: applicationName,
          applicationVersion: applicationVersion,
          analyticsUrl: analyticsUrl,
          analyticsBatchingUrl: analyticsBatchingUrl,
          batchingDelay: batchingDelay,
        ) {
    final locale = getPlatformLocale();
    if (locale != null) {
      setSessionValue('ul', locale);
    }
  }
}

@visibleForTesting
String createUserAgent() {
  final locale = getPlatformLocale() ?? '';

  if (Platform.isAndroid) {
    return 'Mozilla/5.0 (Android; Mobile; ${locale})';
  } else if (Platform.isIOS) {
    return 'Mozilla/5.0 (iPhone; U; CPU iPhone OS like Mac OS X; ${locale})';
  } else if (Platform.isMacOS) {
    return 'Mozilla/5.0 (Macintosh; Intel Mac OS X; Macintosh; ${locale})';
  } else if (Platform.isWindows) {
    return 'Mozilla/5.0 (Windows; Windows; Windows; ${locale})';
  } else if (Platform.isLinux) {
    return 'Mozilla/5.0 (Linux; Linux; Linux; ${locale})';
  } else {
    // Dart/1.8.0 (macos; macos; macos; en_US)
    var os = Platform.operatingSystem;
    return 'Dart/${getDartVersion()} (${os}; ${os}; ${os}; ${locale})';
  }
}

String userHomeDir() {
  var envKey = Platform.operatingSystem == 'windows' ? 'APPDATA' : 'HOME';
  var value = Platform.environment[envKey];
  return value ?? '.';
}

String getDartVersion() {
  var ver = Platform.version;
  var index = ver.indexOf(' ');
  if (index != -1) ver = ver.substring(0, index);
  return ver;
}

class IOPostHandler extends PostHandler {
  final HttpClient _client;

  IOPostHandler({HttpClient? client})
      : _client = (client ?? HttpClient())..userAgent = createUserAgent();

  @override
  String encodeHit(Map<String, String> hit) {
    return postEncode(hit);
  }

  @override
  Future sendPost(String url, List<String> batch) async {
    var data = batch.join('\n');
    try {
      var req = await _client.postUrl(Uri.parse(url));
      req.write(data);
      var response = await req.close();
      await response.drain();
    } on Exception {
      // Catch errors that can happen during a request, but that we can't do
      // anything about, e.g. a missing internet connection.
    }
  }

  @override
  void close() {
    // Do a force close to ensure that lingering requests will not stall the
    // program.
    _client.close(force: true);
  }
}

JsonEncoder _jsonEncoder = JsonEncoder.withIndent('  ');

class IOPersistentProperties extends PersistentProperties {
  late final File _file;
  late Map _map;

  IOPersistentProperties(String name, {String? documentDirPath}) : super(name) {
    var fileName = '.${name.replaceAll(' ', '_')}';
    documentDirPath ??= userHomeDir();
    _file = File(path.join(documentDirPath, fileName));
    if (!_file.existsSync()) {
      _file.createSync();
    }
    syncSettings();
  }

  IOPersistentProperties.fromFile(File file) : super(path.basename(file.path)) {
    _file = file;
    if (!_file.existsSync()) {
      _file.createSync();
    }
    syncSettings();
  }

  @override
  dynamic operator [](String key) => _map[key];

  @override
  void operator []=(String key, dynamic value) {
    if (value == null && !_map.containsKey(key)) return;
    if (_map[key] == value) return;

    if (value == null) {
      _map.remove(key);
    } else {
      _map[key] = value;
    }

    try {
      _file.writeAsStringSync(_jsonEncoder.convert(_map) + '\n');
    } catch (_) {}
  }

  @override
  void syncSettings() {
    try {
      var contents = _file.readAsStringSync();
      if (contents.isEmpty) contents = '{}';
      _map = jsonDecode(contents);
    } catch (_) {
      _map = {};
    }
  }
}

/// Return the string for the platform's locale; return's `null` if the locale
/// can't be determined.
String? getPlatformLocale() {
  var locale = Platform.localeName;

  // Convert `en_US.UTF-8` to `en_US`.
  var index = locale.indexOf('.');
  if (index != -1) locale = locale.substring(0, index);

  // Convert `en_US` to `en-us`.
  locale = locale.replaceAll('_', '-').toLowerCase();

  return locale;
}
