// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import rpc from 'noice-json-rpc';

// To really understand how this works it is useful to see the implementation
// of noice-json-rpc.
export class DevToolsSocket implements rpc.LikeSocket {
  private messageCallback: Function = (_: string) => {};
  private openCallback: Function = () => {};
  private closeCallback: Function = () => {};
  private target: chrome.debugger.Debuggee|undefined;

  constructor() {
    chrome.debugger.onDetach.addListener(this.onDetach.bind(this));
    chrome.debugger.onEvent.addListener((_source, method, params) => {
      if (this.messageCallback) {
        const msg: rpc.JsonRpc2.Notification = {method, params};
        this.messageCallback(JSON.stringify(msg));
      }
    });
  }

  send(message: string): void {
    if (this.target === undefined) return;

    const msg: rpc.JsonRpc2.Request = JSON.parse(message);
    chrome.debugger.sendCommand(
        this.target, msg.method, msg.params, (result) => {
          if (result === undefined) result = {};
          const response: rpc.JsonRpc2.Response = {id: msg.id, result};
          this.messageCallback(JSON.stringify(response));
        });
  }

  // This method will be called once for each event soon after the creation of
  // this object. To understand better what happens, checking the implementation
  // of noice-json-rpc is very useful.
  // While the events "message" and "open" are for implementing the LikeSocket,
  // "close" is a callback set from ChromeTracingController, to reset the state
  // after a detach.
  on(event: string, cb: Function) {
    if (event === 'message') {
      this.messageCallback = cb;
    } else if (event === 'open') {
      this.openCallback = cb;
    } else if (event === 'close') {
      this.closeCallback = cb;
    }
  }

  removeListener(_event: string, _cb: Function) {
    throw new Error('Call unexpected');
  }

  attachToBrowser(then: (error?: string) => void) {
    this.attachToTarget({targetId: 'browser'}, then);
  }

  private attachToTarget(
      target: chrome.debugger.Debuggee, then: (error?: string) => void) {
    chrome.debugger.attach(target, /* requiredVersion=*/ '1.3', () => {
      if (chrome.runtime.lastError) {
        then(chrome.runtime.lastError.message);
        return;
      }
      this.target = target;
      this.openCallback();
      then();
    });
  }

  detach() {
    if (this.target === undefined) return;

    chrome.debugger.detach(this.target, () => {
      this.target = undefined;
    });
  }

  onDetach(_source: chrome.debugger.Debuggee, _reason: string) {
    if (_source === this.target) {
      this.target = undefined;
      this.closeCallback();
    }
  }

  isAttached(): boolean {
    return this.target !== undefined;
  }
}
