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

/**
 * `usage` is a wrapper around Google Analytics for both command-line apps
 * and web apps.
 *
 * In order to use this library as a web app, import the `analytics_html.dart`
 * library and instantiate the [AnalyticsHtml] class.
 *
 * In order to use this library as a command-line app, import the
 * `analytics_io.dart` library and instantiate the [AnalyticsIO] class.
 *
 * For both classes, you need to provide a Google Analytics tracking ID, the
 * application name, and the application version.
 *
 * Your application should provide an opt-in option for the user. If they
 * opt-in, set the [optIn] field to `true`. This setting will persist across
 * sessions automatically.
 *
 * For more information, please see the Google Analytics Measurement Protocol
 * [Policy](https://developers.google.com/analytics/devguides/collection/protocol/policy).
 */
library usage;

import 'dart:async';

import 'src/usage_impl_default.dart'
   if (dart.library.js) 'src/usage_impl_html.dart'
   if (dart.library.ui) 'src/usage_impl_flutter.dart'
   if (dart.library.io) 'src/usage_impl_io.dart'
   as impl;

// Matches file:/, non-ws, /, non-ws, .dart
final RegExp _pathRegex = new RegExp(r'file:/\S+/(\S+\.dart)');

/**
 * An interface to a Google Analytics session. You'll get the correct one
 * for your platform by calling the [Analytics.create] static method.
 * [AnalyticsMock] can be used for testing or for some variants of an opt-in
 * workflow.
 *
 * The analytics information is sent on a best-effort basis. So, failures to
 * send the GA information will not result in errors from the asynchronous
 * `send` methods.
 */
abstract class Analytics {
  static Future<Analytics> create(
    String trackingId,
    String applicationName,
    String applicationVersion, {
    String analyticsUrl
  }) => impl.createAnalytics(trackingId, applicationName, applicationVersion,
    analyticsUrl: analyticsUrl);

  /**
   * Tracking ID / Property ID.
   */
  String get trackingId;

  /**
   * Whether the user has opt-ed in to additional analytics.
   */
  bool get optIn;

  set optIn(bool value);

  /**
   * Whether the [optIn] value has been explicitly set (either `true` or
   * `false`).
   */
  bool get hasSetOptIn;

  /**
   * Sends a screen view hit to Google Analytics.
   */
  Future sendScreenView(String viewName);

  /**
   * Sends an Event hit to Google Analytics. [label] specifies the event label.
   * [value] specifies the event value. Values must be non-negative.
   */
  Future sendEvent(String category, String action, {String label, int value});

  /**
   * Sends a Social hit to Google Analytics. [network] specifies the social
   * network, for example Facebook or Google Plus. [action] specifies the social
   * interaction action. For example on Google Plus when a user clicks the +1
   * button, the social action is 'plus'. [target] specifies the target of a
   * social interaction. This value is typically a URL but can be any text.
   */
  Future sendSocial(String network, String action, String target);

  /**
   * Sends a Timing hit to Google Analytics. [variableName] specifies the
   * variable name of the timing. [time] specifies the user timing value (in
   * milliseconds). [category] specifies the category of the timing. [label]
   * specifies the label of the timing.
   */
  Future sendTiming(String variableName, int time, {String category,
      String label});

  /**
   * Start a timer. The time won't be calculated, and the analytics information
   * sent, until the [AnalyticsTimer.finish] method is called.
   */
  AnalyticsTimer startTimer(String variableName,
      {String category, String label});

  /**
   * In order to avoid sending any personally identifying information, the
   * [description] field must not contain the exception message. In addition,
   * only the first 100 chars of the description will be sent.
   */
  Future sendException(String description, {bool fatal});

  /**
   * Sets a session variable value. The value is persistent for the life of the
   * [Analytics] instance. This variable will be sent in with every analytics
   * hit. A list of valid variable names can be found here:
   * https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters.
   */
  void setSessionValue(String param, dynamic value);

  /**
   * Wait for all of the outstanding analytics pings to complete. The returned
   * `Future` will always complete without errors. You can pass in an optional
   * `Duration` to specify to only wait for a certain amount of time.
   *
   * This method is particularly useful for command-line clients. Outstanding
   * I/O requests will cause the VM to delay terminating the process. Generally,
   * users won't want their CLI app to pause at the end of the process waiting
   * for Google analytics requests to complete. This method allows CLI apps to
   * delay for a short time waiting for GA requests to complete, and then do
   * something like call `exit()` explicitly themselves.
   */
  Future waitForLastPing({Duration timeout});
}

/**
 * An object, returned by [Analytics.startTimer], that is used to measure an
 * asynchronous process.
 */
class AnalyticsTimer {
  final Analytics analytics;
  final String variableName;
  final String category;
  final String label;

  int _startMillis;
  int _endMillis;

  AnalyticsTimer(this.analytics, this.variableName,
      {this.category, this.label}) {
    _startMillis = new DateTime.now().millisecondsSinceEpoch;
  }

  int get currentElapsedMillis {
    if (_endMillis == null) {
      return new DateTime.now().millisecondsSinceEpoch - _startMillis;
    } else {
      return _endMillis - _startMillis;
    }
  }

  /**
   * Finish the timer, calculate the elapsed time, and send the information to
   * analytics. Once this is called, any future invocations are no-ops.
   */
  Future finish() {
    if (_endMillis != null) return new Future.value();

    _endMillis = new DateTime.now().millisecondsSinceEpoch;
    return analytics.sendTiming(
        variableName, currentElapsedMillis, category: category, label: label);
  }
}

/**
 * A no-op implementation of the [Analytics] class. This can be used as a
 * stand-in for that will never ping the GA server, or as a mock in test code.
 */
class AnalyticsMock implements Analytics {
  String get trackingId => 'UA-0';
  final bool logCalls;

  bool optIn = false;
  bool hasSetOptIn = true;

  /**
   * Create a new [AnalyticsMock]. If [logCalls] is true, all calls will be
   * logged to stdout.
   */
  AnalyticsMock([this.logCalls = false]);

  Future sendScreenView(String viewName) =>
      _log('screenView', {'viewName': viewName});

  Future sendEvent(String category, String action, {String label, int value}) {
    return _log('event', {'category': category, 'action': action,
      'label': label, 'value': value});
  }

  Future sendSocial(String network, String action, String target) =>
      _log('social', {'network': network, 'action': action, 'target': target});

  Future sendTiming(String variableName, int time, {String category,
      String label}) {
    return _log('timing', {'variableName': variableName, 'time': time,
      'category': category, 'label': label});
  }

  AnalyticsTimer startTimer(String variableName,
      {String category, String label}) {
    return new AnalyticsTimer(this,
        variableName, category: category, label: label);
  }

  Future sendException(String description, {bool fatal}) =>
      _log('exception', {'description': description, 'fatal': fatal});

  void setSessionValue(String param, dynamic value) { }

  Future waitForLastPing({Duration timeout}) => new Future.value();

  Future _log(String hitType, Map m) {
    if (logCalls) {
      print('analytics: ${hitType} ${m}');
    }

    return new Future.value();
  }
}

/**
 * Sanitize a stacktrace. This will shorten file paths in order to remove any
 * PII that may be contained in the full file path. For example, this will
 * shorten `file:///Users/foobar/tmp/error.dart` to `error.dart`.
 *
 * If [shorten] is `true`, this method will also attempt to compress the text
 * of the stacktrace. GA has a 100 char limit on the text that can be sent for
 * an exception. This will try and make those first 100 chars contain
 * information useful to debugging the issue.
 */
String sanitizeStacktrace(dynamic st, {bool shorten: true}) {
  String str = '${st}';

  Iterable<Match> iter = _pathRegex.allMatches(str);
  iter = iter.toList().reversed;

  for (Match match in iter) {
    String replacement = match.group(1);
    str = str.substring(0, match.start)
        + replacement + str.substring(match.end);
  }

  if (shorten) {
    // Shorten the stacktrace up a bit.
    str = str
        .replaceAll('(package:', '(')
        .replaceAll('(dart:', '(')
        .replaceAll(new RegExp(r'\s+'), ' ');
  }

  return str;
}
