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

import 'dart:async';
import 'dart:collection';

import '../webkit_inspection_protocol.dart';

class WipDebugger extends WipDomain {
  final _scripts = <String, WipScript>{};

  WipDebugger(WipConnection connection) : super(connection) {
    onScriptParsed.listen((event) {
      _scripts[event.script.scriptId] = event.script;
    });
    onGlobalObjectCleared.listen((_) {
      _scripts.clear();
    });
  }

  Future enable() => sendCommand('Debugger.enable');
  Future disable() => sendCommand('Debugger.disable');

  Future<String> getScriptSource(String scriptId) async =>
      (await sendCommand('Debugger.getScriptSource',
              params: {'scriptId': scriptId}))
          .result['scriptSource'] as String;

  Future pause() => sendCommand('Debugger.pause');
  Future resume() => sendCommand('Debugger.resume');

  Future stepInto() => sendCommand('Debugger.stepInto');
  Future stepOut() => sendCommand('Debugger.stepOut');
  Future stepOver() => sendCommand('Debugger.stepOver');

  Future setPauseOnExceptions(PauseState state) =>
      sendCommand('Debugger.setPauseOnExceptions',
          params: {'state': _pauseStateToString(state)});

  Stream<DebuggerPausedEvent> get onPaused => eventStream(
      'Debugger.paused', (WipEvent event) => new DebuggerPausedEvent(event));
  Stream<GlobalObjectClearedEvent> get onGlobalObjectCleared => eventStream(
      'Debugger.globalObjectCleared',
      (WipEvent event) => new GlobalObjectClearedEvent(event));
  Stream<DebuggerResumedEvent> get onResumed => eventStream(
      'Debugger.resumed', (WipEvent event) => new DebuggerResumedEvent(event));
  Stream<ScriptParsedEvent> get onScriptParsed => eventStream(
      'Debugger.scriptParsed',
      (WipEvent event) => new ScriptParsedEvent(event));

  Map<String, WipScript> get scripts => new UnmodifiableMapView(_scripts);
}

String _pauseStateToString(PauseState state) {
  switch (state) {
    case PauseState.all:
      return 'all';
    case PauseState.none:
      return 'none';
    case PauseState.uncaught:
      return 'uncaught';
    default:
      throw new ArgumentError('unknown state: $state');
  }
}

enum PauseState { all, none, uncaught }

class ScriptParsedEvent extends WrappedWipEvent {
  final WipScript script;

  ScriptParsedEvent(WipEvent event)
      : this.script = new WipScript(event.params),
        super(event);
}

class GlobalObjectClearedEvent extends WrappedWipEvent {
  GlobalObjectClearedEvent(WipEvent event) : super(event);
}

class DebuggerResumedEvent extends WrappedWipEvent {
  DebuggerResumedEvent(WipEvent event) : super(event);
}

class DebuggerPausedEvent extends WrappedWipEvent {
  DebuggerPausedEvent(WipEvent event) : super(event);

  String get reason => params['reason'] as String;
  Object get data => params['data'];

  Iterable<WipCallFrame> getCallFrames() => (params['callFrames'] as List)
      .map((frame) => new WipCallFrame(frame as Map<String, dynamic>));

  String toString() => 'paused: ${reason}';
}

class WipCallFrame {
  final Map<String, dynamic> _map;

  WipCallFrame(this._map);

  String get callFrameId => _map['callFrameId'] as String;
  String get functionName => _map['functionName'] as String;
  WipLocation get location =>
      new WipLocation(_map['location'] as Map<String, dynamic>);
  WipRemoteObject get thisObject =>
      new WipRemoteObject(_map['this'] as Map<String, dynamic>);

  Iterable<WipScope> getScopeChain() => (_map['scopeChain'] as List)
      .map((scope) => new WipScope(scope as Map<String, dynamic>));

  String toString() => '[${functionName}]';
}

class WipLocation {
  final Map<String, dynamic> _map;

  WipLocation(this._map);

  int get columnNumber => _map['columnNumber'] as int;
  int get lineNumber => _map['lineNumber'] as int;
  String get scriptId => _map['scriptId'] as String;

  String toString() => '[${scriptId}:${lineNumber}:${columnNumber}]';
}

class WipRemoteObject {
  final Map<String, dynamic> _map;

  WipRemoteObject(this._map);

  String get className => _map['className'] as String;
  String get description => _map['description'] as String;
  String get objectId => _map['objectId'] as String;
  String get subtype => _map['subtype'] as String;
  String get type => _map['type'] as String;
  Object get value => _map['value'];
}

class WipScript {
  final Map<String, dynamic> _map;

  WipScript(this._map);

  String get scriptId => _map['scriptId'] as String;
  String get url => _map['url'] as String;
  int get startLine => _map['startLine'] as int;
  int get startColumn => _map['startColumn'] as int;
  int get endLine => _map['endLine'] as int;
  int get endColumn => _map['endColumn'] as int;
  bool get isContentScript => _map['isContentScript'] as bool;
  String get sourceMapURL => _map['sourceMapURL'] as String;

  String toString() => '[script ${scriptId}: ${url}]';
}

class WipScope {
  final Map<String, dynamic> _map;

  WipScope(this._map);

  // "catch", "closure", "global", "local", "with"
  String get scope => _map['type'] as String;

  /// Object representing the scope. For global and with scopes it represents
  /// the actual object; for the rest of the scopes, it is artificial transient
  /// object enumerating scope variables as its properties.
  WipRemoteObject get object =>
      new WipRemoteObject(_map['object'] as Map<String, dynamic>);
}
