// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library tracing;

import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:core';
import 'dart:io';
import 'dart:isolate';

import 'package:common/src/trace_provider_impl.dart';
export 'package:common/src/trace_provider_impl.dart' show TraceSendTiming;

import 'package:mojo/application.dart';
import 'package:mojo/core.dart';
import 'package:mojo_services/tracing/tracing.mojom.dart';

// Phases indicating the nature of the event in the trace log.
// These should be in sync with definitions in
// //base/trace_event/trace_event.h
const traceEventInstant = "I";
const traceEventPhaseBegin = "B";
const traceEventPhaseEnd = "E";
const traceEventPhaseAsyncBegin = "S";
const traceEventPhaseAsyncEnd = "F";
const traceEventDuration = "X";

// TracingHelper is used by Dart code running in the Mojo shell in order
// to perform tracing.
class TracingHelper {
  TraceProviderImpl _impl;
  int _tid;
  static TracingHelper _tracing;
  // Construct an instance of TracingHelper from within your application's
  // |initialize()| method. |appName| will be used to form a thread identifier
  // for use in trace messages. If |appName| is longer than 20 characters then
  // only the last 20 characters of |appName| will be used.
  TracingHelper.fromApplication(Application app, String appName,
      [TraceSendTiming timing = TraceSendTiming.IMMEDIATE]) {
    // Masked because the tid is expected to be a 32-bit int.
    _tid = [appName, Isolate.current]
            .fold(7, (hash, element) => 31 * hash + element.hashCode) &
        0x7fffffff;
    _impl = new TraceProviderImpl(timing);
    ApplicationConnection connection = app.connectToApplication("mojo:tracing");
    connection.provideService(TraceProviderName, (e) {
      _impl.connect(e);
    });
    assert(_tracing == null);
    _tracing = this;
  }

  // Factory to return the singleton instance of the TracingHelper. The isolate
  // must have constructed the object using TracingHelper.fromApplication
  // atleast once before using this factory.
  factory TracingHelper() {
    assert(_tracing != null);
    return _tracing;
  }

  bool isActive() {
    return (_impl != null) && _impl.isActive();
  }

  // Invoke this at the beginning of a synchronous function whose
  // duration you wish to trace. Invoke |end()| on the returned object.
  FunctionTrace begin(String functionName, String categories,
      {Map<String, String> args}) {
    return _beginFunction(functionName, categories, traceEventPhaseBegin,
        args: args);
  }

  // Invoke this right before an asynchronous function whose duration
  // you wish to trace. Invoke |end()| on the returned object.
  FunctionTrace beginAsync(String functionName, String categories,
      {Map<String, String> args}) {
    return _beginFunction(functionName, categories, traceEventPhaseAsyncBegin,
        args: args);
  }

  void traceInstant(String name, String categories,
      {Map<String, String> args}) {
    _sendTraceMessage(name, categories, traceEventInstant, 0, args: args);
  }

  void traceDuration(String name, String categories, int start, int end,
      {Map<String, String> args}) {
    _sendTraceMessage(name, categories, traceEventDuration, 0,
        args: args, start: start, duration: end - start);
  }

  FunctionTrace _beginFunction(
      String functionName, String categories, String phase,
      {Map<String, String> args}) {
    assert(functionName != null);
    final trace = new _FunctionTraceImpl(
        this, isActive() ? functionName : null, categories, phase);
    _sendTraceMessage(functionName, categories, phase, trace.hashCode,
        args: args);
    return trace;
  }

  void _endFunction(
      String functionName, String categories, String phase, int traceId) {
    _sendTraceMessage(functionName, categories, phase, traceId);
  }

  void _sendTraceMessage(
      String name, String categories, String phase, int traceId,
      {Map<String, String> args, int start, int duration}) {
    if (isActive()) {
      var time = (start != null) ? start : getTimeTicksNow();
      var map = new HashMap();
      map["name"] = name;
      map["cat"] = categories;
      map["ph"] = phase;
      map["ts"] = time;
      map["pid"] = pid;
      map["tid"] = _tid;
      map["id"] = traceId;
      if (duration != null) {
        map["dur"] = duration;
      }
      if (args != null) {
        map["args"] = args;
      }
      _impl.sendTraceMessage(JSON.encode(map));
    }
  }

  // A convenience method that wraps a closure in a begin-end pair of
  // tracing calls.
  dynamic trace(String functionName, String categories, closure(),
      {Map<String, String> args}) {
    FunctionTrace ft = begin(functionName, categories, args: args);
    final returnValue = closure();
    ft.end();
    return returnValue;
  }

  // A convenience method that wraps a closure in a begin-end pair of
  // async tracing calls. The return value should either be returned or awaited.
  Future traceAsync(String functionName, String categories, Future closure(),
      {Map<String, String> args}) {
    FunctionTrace ft = beginAsync(functionName, categories, args: args);
    final Future returnValue = closure();
    returnValue.whenComplete(ft.end);
    return returnValue;
  }
}

// An instance of FunctionTrace is returned from |begin()|, |beginAsync()|.
// Invoke |end()| to end the trace from every exit point in the function you are
// tracing.
abstract class FunctionTrace {
  void end();
}

class _FunctionTraceImpl implements FunctionTrace {
  TracingHelper _tracing;
  String _functionName;
  String _categories;
  String _beginPhase;

  _FunctionTraceImpl(
      this._tracing, this._functionName, this._categories, this._beginPhase) {
    assert(_beginPhase == traceEventPhaseBegin ||
        _beginPhase == traceEventPhaseAsyncBegin);
  }

  @override
  void end() {
    if (_functionName != null) {
      if (_beginPhase == traceEventPhaseBegin) {
        _tracing._endFunction(
            _functionName, _categories, traceEventPhaseEnd, hashCode);
      } else if (_beginPhase == traceEventPhaseAsyncBegin) {
        _tracing._endFunction(
            _functionName, _categories, traceEventPhaseAsyncEnd, hashCode);
      }
    }
  }
}
