<!DOCTYPE html>
<!--
Copyright (c) 2013 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.
-->

<link rel="import" href="/tracing/ui/extras/about_tracing/record_selection_dialog.html">

<script>
'use strict';

tr.exportTo('tr.ui.e.about_tracing', function() {
  function beginMonitoring(tracingControllerClient) {
    var finalPromiseResolver;
    var finalPromise = new Promise(function(resolve, reject) {
      finalPromiseResolver = {
        resolve: resolve,
        reject: reject
      };
    });

    // TODO(haraken): Implement a configure dialog to set these options.
    var monitoringOptions = {
      categoryFilter: '*',
      useSystemTracing: false,
      tracingRecordMode: 'record-until-full',
      useSampling: true
    };


    var beginMonitoringPromise = tracingControllerClient.beginMonitoring(
        monitoringOptions);

    beginMonitoringPromise.then(
        function() {
          finalPromiseResolver.resolve();
        },
        function(err) {
          finalPromiseResolver.reject(err);
        });

    return finalPromise;
  }

  function endMonitoring(tracingControllerClient) {
    var endMonitoringPromise = tracingControllerClient.endMonitoring();
    return endMonitoringPromise.then(
        function() {
        },
        function(err) {
        });
  }

  function captureMonitoring(tracingControllerClient) {
    var captureMonitoringPromise =
        tracingControllerClient.captureMonitoring();
    return captureMonitoringPromise;
  }

  function getMonitoringStatus(tracingControllerClient) {
    var getMonitoringStatusPromise =
        tracingControllerClient.getMonitoringStatus();
    return getMonitoringStatusPromise;
  }

  function beginRecording(tracingControllerClient) {
    var finalPromiseResolver;
    var finalPromise = new Promise(function(resolve, reject) {
      finalPromiseResolver = {
        resolve: resolve,
        reject: reject
      };
    });
    finalPromise.selectionDlg = undefined;
    finalPromise.progressDlg = undefined;

    function beginRecordingError(err) {
      finalPromiseResolver.reject(err);
    }

    // Step 0: End recording. This is necessary when the user reloads the
    // about:tracing page when we are recording. Window.onbeforeunload is not
    // reliable to end recording on reload.
    endRecording(tracingControllerClient).then(
        getCategories,
        getCategories);  // Ignore error.

    // But just in case, bind onbeforeunload anyway.
    window.onbeforeunload = function(e) {
      endRecording(tracingControllerClient);
    }

    // Step 1: Get categories.
    function getCategories() {
      var p = tracingControllerClient.getCategories().then(
          showTracingDialog,
          beginRecordingError);
      p.catch(function(err) {
        beginRecordingError(err);
      });
    }

    // Step 2: Show tracing dialog.
    var selectionDlg;
    function showTracingDialog(categories) {
      selectionDlg = new tr.ui.e.about_tracing.RecordSelectionDialog();
      selectionDlg.categories = categories;
      selectionDlg.settings_key =
          'tr.ui.e.about_tracing.record_selection_dialog';
      selectionDlg.addEventListener('recordclick', startTracing);
      selectionDlg.addEventListener('closeclick', cancelRecording);
      selectionDlg.visible = true;

      finalPromise.selectionDlg = selectionDlg;
    }

    function cancelRecording() {
      finalPromise.selectionDlg = undefined;
      finalPromiseResolver.reject(new UserCancelledError());
    }

    // Step 2: Do the actual tracing dialog.
    var progressDlg;
    var bufferPercentFullDiv;
    function startTracing() {
      progressDlg = new tr.ui.b.Overlay();
      progressDlg.textContent = 'Recording...';
      progressDlg.userCanClose = false;

      bufferPercentFullDiv = document.createElement('div');
      progressDlg.appendChild(bufferPercentFullDiv);

      var stopButton = document.createElement('button');
      stopButton.textContent = 'Stop';
      progressDlg.clickStopButton = function() {
        stopButton.click();
      };
      progressDlg.appendChild(stopButton);

      var recordingOptions = {
        categoryFilter: selectionDlg.categoryFilter(),
        useSystemTracing: selectionDlg.useSystemTracing,
        tracingRecordMode: selectionDlg.tracingRecordMode,
        useSampling: selectionDlg.useSampling
      };


      var requestPromise = tracingControllerClient.beginRecording(
          recordingOptions);
      requestPromise.then(
          function() {
            progressDlg.visible = true;
            stopButton.focus();
            updateBufferPercentFull('0');
          },
          recordFailed);

      stopButton.addEventListener('click', function() {
        // TODO(chrishenry): Currently, this only dismiss the progress
        // dialog when tracingComplete event is received. When performing
        // remote debugging, the tracingComplete event may be delayed
        // considerable. We should indicate to user that we are waiting
        // for tracingComplete event instead of being unresponsive. (For
        // now, I disable the "stop" button, since clicking on the button
        // again now cause exception.)
        var recordingPromise = endRecording(tracingControllerClient);
        recordingPromise.then(
            recordFinished,
            recordFailed);
        stopButton.disabled = true;
        bufferPercentFullDiv = undefined;
      });
      finalPromise.progressDlg = progressDlg;
    }

    function recordFinished(tracedData) {
      progressDlg.visible = false;
      finalPromise.progressDlg = undefined;
      finalPromiseResolver.resolve(tracedData);
    }

    function recordFailed(err) {
      progressDlg.visible = false;
      finalPromise.progressDlg = undefined;
      finalPromiseResolver.reject(err);
    }

    function getBufferPercentFull() {
      if (!bufferPercentFullDiv)
        return;

      tracingControllerClient.beginGetBufferPercentFull().then(
          updateBufferPercentFull);
    }

    function updateBufferPercentFull(percent_full) {
      if (!bufferPercentFullDiv)
        return;

      percent_full = Math.round(100 * parseFloat(percent_full));
      var newText = 'Buffer usage: ' + percent_full + '%';
      if (bufferPercentFullDiv.textContent != newText)
        bufferPercentFullDiv.textContent = newText;

      window.setTimeout(getBufferPercentFull, 500);
    }

    // Thats it! We're done.
    return finalPromise;
  };

  function endRecording(tracingControllerClient) {
    return tracingControllerClient.endRecording();
  }

  function defaultTraceName(tracingControllerClient) {
    return tracingControllerClient.defaultTraceName();
  }

  function UserCancelledError() {
    Error.apply(this, arguments);
  }
  UserCancelledError.prototype = {
    __proto__: Error.prototype
  };

  return {
    beginRecording: beginRecording,
    beginMonitoring: beginMonitoring,
    endMonitoring: endMonitoring,
    captureMonitoring: captureMonitoring,
    getMonitoringStatus: getMonitoringStatus,
    UserCancelledError: UserCancelledError,
    defaultTraceName: defaultTraceName
  };
});
</script>
