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

part of dart.developer;

const bool _isProduct = const bool.fromEnvironment("dart.vm.product");

typedef dynamic TimelineSyncFunction();
typedef Future TimelineAsyncFunction();

/// Add to the timeline.
class Timeline {
  /// Start a synchronous operation labeled [name]. Optionally takes
  /// a [Map] of [arguments]. This operation must be finished before
  /// returning to the event queue.
  static void startSync(String name, {Map arguments}) {
    if (_isProduct) {
      return;
    }
    if (name is! String) {
      throw new ArgumentError.value(name,
                                    'name',
                                    'Must be a String');
    }
    var block = new _SyncBlock._(name, _getTraceClock(), _getThreadCpuClock());
    if (arguments is Map) {
      block._appendArguments(arguments);
    }
    _stack.add(block);
  }

  /// Finish the last synchronous operation that was started.
  static void finishSync() {
    if (_isProduct) {
      return;
    }
    if (_stack.length == 0) {
      throw new StateError(
          'Uneven calls to startSync and finishSync');
    }
    // Pop top item off of stack.
    var block = _stack.removeLast();
    // Finish it.
    block.finish();
  }

  /// Emit an instant event.
  static void instantSync(String name, {Map arguments}) {
    if (_isProduct) {
      return;
    }
    if (name is! String) {
      throw new ArgumentError.value(name,
                                    'name',
                                    'Must be a String');
    }
    Map instantArguments;
    if (arguments is Map) {
      instantArguments = new Map.from(arguments);
    }
    _reportInstantEvent(_getTraceClock(),
                        'Dart',
                        name,
                        _argumentsAsJson(instantArguments));
  }


  /// A utility method to time a synchronous [function]. Internally calls
  /// [function] bracketed by calls to [startSync] and [finishSync].
  static dynamic timeSync(String name,
                          TimelineSyncFunction function,
                          {Map arguments}) {
    startSync(name, arguments: arguments);
    try {
      return function();
    } finally {
      finishSync();
    }
  }

  /// The current time stamp from the clock used by the timeline. Units are
  /// microseconds.
  static int get now => _getTraceClock();
  static final List<_SyncBlock> _stack = new List<_SyncBlock>();
  static final int _isolateId = _getIsolateNum();
  static final String _isolateIdString = _isolateId.toString();
}

/// An asynchronous task on the timeline. An asynchronous task can have many
/// (nested) synchronous operations. Synchronous operations can live longer than
/// the current isolate event. To pass a [TimelineTask] to another isolate,
/// you must first call [pass] to get the task id and then construct a new
/// [TimelineTask] in the other isolate.
class TimelineTask {
  /// Create a task. [taskId] will be set by the system.
  TimelineTask()
      : _taskId = _getNextAsyncId() {
  }

  /// Create a task with an explicit [taskId]. This is useful if you are
  /// passing a task from one isolate to another.
  TimelineTask.withTaskId(int taskId)
      : _taskId = taskId {
    if (taskId is! int) {
      throw new ArgumentError.value(taskId,
                                    'taskId',
                                    'Must be an int');
    }
  }

  /// Start a synchronous operation within this task named [name].
  /// Optionally takes a [Map] of [arguments].
  void start(String name, {Map arguments}) {
    if (_isProduct) {
      return;
    }
    if (name is! String) {
      throw new ArgumentError.value(name,
                                    'name',
                                    'Must be a String');
    }
    var block = new _AsyncBlock._(name, _taskId);
    if (arguments is Map) {
      block._appendArguments(arguments);
    }
    _stack.add(block);
    block._start();
  }

  /// Emit an instant event for this task.
  void instant(String name, {Map arguments}) {
    if (_isProduct) {
      return;
    }
    if (name is! String) {
      throw new ArgumentError.value(name,
                                    'name',
                                    'Must be a String');
    }
    Map instantArguments;
    if (arguments is Map) {
      instantArguments = new Map.from(arguments);
    }
    _reportTaskEvent(_getTraceClock(),
                     _taskId,
                     'n',
                     'Dart',
                     name,
                     _argumentsAsJson(instantArguments));
  }

  /// Finish the last synchronous operation that was started.
  void finish() {
    if (_isProduct) {
      return;
    }
    if (_stack.length == 0) {
      throw new StateError(
          'Uneven calls to start and finish');
    }
    // Pop top item off of stack.
    var block = _stack.removeLast();
    block._finish();
  }

  /// Retrieve the [TimelineTask]'s task id. Will throw an exception if the
  /// stack is not empty.
  int pass() {
    if (_stack.length > 0) {
      throw new StateError(
          'You cannot pass a TimelineTask without finishing all started '
          'operations');
    }
    int r = _taskId;
    return r;
  }

  final int _taskId;
  final List<_AsyncBlock> _stack = [];
}

/// An asynchronous block of time on the timeline. This block can be kept
/// open across isolate messages.
class _AsyncBlock {
  /// The category this block belongs to.
  final String category = 'Dart';
  /// The name of this block.
  final String name;
  /// The asynchronous task id.
  final int _taskId;
  /// An (optional) set of arguments which will be serialized to JSON and
  /// associated with this block.
  Map _arguments;

  _AsyncBlock._(this.name, this._taskId);

  // Emit the start event.
  void _start() {
    _reportTaskEvent(_getTraceClock(),
                     _taskId,
                     'b',
                     category,
                     name,
                     _argumentsAsJson(_arguments));
  }

  // Emit the finish event.
  void _finish() {
    _reportTaskEvent(_getTraceClock(),
                     _taskId,
                     'e',
                     category,
                     name,
                     _argumentsAsJson(null));
  }

  void _appendArguments(Map arguments) {
    if (_arguments == null) {
      _arguments = {};
    }
    _arguments.addAll(arguments);
  }
}

/// A synchronous block of time on the timeline. This block should not be
/// kept open across isolate messages.
class _SyncBlock {
  /// The category this block belongs to.
  final String category = 'Dart';
  /// The name of this block.
  final String name;
  /// An (optional) set of arguments which will be serialized to JSON and
  /// associated with this block.
  Map _arguments;
  // The start time stamp.
  final int _start;
  // The start time stamp of the thread cpu clock.
  final int _startCpu;

  _SyncBlock._(this.name,
               this._start,
               this._startCpu);

  /// Finish this block of time. At this point, this block can no longer be
  /// used.
  void finish() {
    // Report event to runtime.
    _reportCompleteEvent(_start,
                         _startCpu,
                         category,
                         name,
                         _argumentsAsJson(_arguments));
  }

  void _appendArguments(Map arguments) {
    if (arguments == null) {
      return;
    }
    if (_arguments == null) {
      _arguments = {};
    }
    _arguments.addAll(arguments);
  }
}

String _fastPathArguments;
String _argumentsAsJson(Map arguments) {
  if ((arguments == null) || (arguments.length == 0)) {
    // Fast path no arguments. Avoid calling JSON.encode.
    if (_fastPathArguments == null) {
      _fastPathArguments = '{"isolateNumber":"${Timeline._isolateId}"}';
    }
    return _fastPathArguments;
  }
  // Add isolateNumber to arguments map.
  arguments['isolateNumber'] = Timeline._isolateIdString;
  return JSON.encode(arguments);
}

/// Returns the next async task id.
external int _getNextAsyncId();

/// Returns the current value from the trace clock.
external int _getTraceClock();

/// Returns the current value from the thread CPU usage clock.
external int _getThreadCpuClock();

/// Returns the isolate's main port number.
external int _getIsolateNum();

/// Reports an event for a task.
external void _reportTaskEvent(int start,
                               int taskId,
                               String phase,
                               String category,
                               String name,
                               String argumentsAsJson);

/// Reports a complete synchronous event.
external void _reportCompleteEvent(int start,
                                   int startCpu,
                                   String category,
                                   String name,
                                   String argumentsAsJson);

/// Reports an instant event.
external void _reportInstantEvent(int start,
                                  String category,
                                  String name,
                                  String argumentsAsJson);
