<import src="/mojo/public/sky/connection.sky" as="connection" />
<import src="/mojo/public/sky/core.sky" as="core" />
<import src="/mojo/public/sky/support.sky" as="support" />
<import src="/mojo/services/public/sky/application.sky" as="application" />
<import src="/sky/services/inspector/inspector.mojom.sky" as="inspector" />
<import src="console-agent.sky" as="ConsoleAgent" />
<import src="dom-agent.sky" as="DOMAgent" />
<import src="page-agent.sky" as="PageAgent" />
<import src="worker-agent.sky" as="WorkerAgent" />
<import src="runtime-agent.sky" as="RuntimeAgent" />
<import src="indexeddb-agent.sky" as="IndexedDBAgent" />
<import src="css-agent.sky" as="CSSAgent" />
<script>
class InspectorBackend extends inspector.InspectorBackend.stubClass {
  constructor(frontend) {
    var domAgent = new DOMAgent(this);
    this.agents = {
      Console: new ConsoleAgent(),
      DOM: domAgent,
      Page: new PageAgent(this),
      Worker: new WorkerAgent(),
      Runtime: new RuntimeAgent(this),
      CSS: new CSSAgent(domAgent),
      IndexedDB: new IndexedDBAgent(),
    };
    this.missingNames_ = {};
    this.unansweredMessages_ = [];

    this.IMPLEMENTED_IN_CPP = "IMPLEMENTED_IN_CPP";
    this.ASYNC_RESPONSE = "ASYNC_RESPONSE";
    this.MESSAGE_TIMEOUT_MS = 30000;

    Object.preventExtensions(this);
  }

  onConnect() {
  }

  onDisconnect() {
  }

  logMissing_(name) {
    if (name in this.missingNames_)
      return;
    this.missingNames_[name] = true;
    console.log("InspectorBackend missing " + name);
  }

  dispatch_(descriptor, params, message_id) {
    var parsed = descriptor.split('.');

    var agentName = parsed[0];
    var methodName = parsed[1];

    // Debugger is implemented in c++.
    if (agentName == "Debugger")
      return this.IMPLEMENTED_IN_CPP;

    if (!(agentName in this.agents)) {
      this.logMissing_(agentName);
      return {};
    }

    var agent = this.agents[agentName];

    if (!(methodName in agent)) {
      this.logMissing_(descriptor);
      return {};
    }

    try {
      return agent[methodName](params, message_id);
    } catch(ex) {
      console.log(descriptor + ": " + ex);
    }
  }

  onMessage(data) {
    var message = JSON.parse(data);
    var result = this.dispatch_(message.method, message.params, message.id);
    if (result === this.IMPLEMENTED_IN_CPP)
      return;
    this.unansweredMessages_.push(message.id);
    // FIXME: This magic return value is kinda hacky.
    if (result !== this.ASYNC_RESPONSE)
      this.sendResponse(message.id, result);
    else {
      window.setTimeout(function() {
        if (this.unansweredMessages_.indexOf(message.id) == -1)
          return;
        console.log("Error, failed to reply to message id " + message.id);
      }.bind(this), this.MESSAGE_TIMEOUT_MS);
    }
  }

  sendResponse(message_id, result) {
    var messageIndex = this.unansweredMessages_.indexOf(message_id);
    if (messageIndex != -1)
      this.unansweredMessages_.splice(messageIndex, 1);
    else
      console.log("Error, responding to unknown message id " + message_id);
    var response = {
      id: message_id,
    };
    if (typeof result !== "undefined")
      response.result = result;
    window.frontend.sendMessage(JSON.stringify(response));
  }

  sendMessage(method, params) {
    var message = JSON.stringify({
      method: method,
      params: params,
    });
    window.frontend.sendMessage(message);
  }
}

(function() {
  var app = new application.Application(internals.passShellProxyHandle());
  var tracingApp = app.shell.connectToApplication("mojo:sky_inspector_server");
  tracingApp.provideService(inspector.InspectorBackend, InspectorBackend);

  window.frontend = tracingApp.requestService(inspector.InspectorFrontend);
})();
</script>
