// 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';

/// Implementation of the
/// https://developer.chrome.com/devtools/docs/protocol/1.1/dom
class WipDom extends WipDomain {
  WipDom(WipConnection connection) : super(connection);

  Future<Map<String, String>> getAttributes(int nodeId) async {
    WipResponse resp =
        await sendCommand('DOM.getAttributes', params: {'nodeId': nodeId});
    return _attributeListToMap((resp.result['attributes'] as List).cast());
  }

  Future<Node> getDocument() async =>
      new Node((await sendCommand('DOM.getDocument')).result['root']
          as Map<String, dynamic>);

  Future<String> getOuterHtml(int nodeId) async =>
      (await sendCommand('DOM.getOuterHTML', params: {'nodeId': nodeId}))
          .result['root'] as String;

  Future hideHighlight() => sendCommand('DOM.hideHighlight');

  Future highlightNode(int nodeId,
      {Rgba borderColor,
      Rgba contentColor,
      Rgba marginColor,
      Rgba paddingColor,
      bool showInfo}) {
    var params = <String, dynamic>{'nodeId': nodeId, 'highlightConfig': {}};

    if (borderColor != null) {
      params['highlightConfig']['borderColor'] = borderColor;
    }

    if (contentColor != null) {
      params['highlightConfig']['contentColor'] = contentColor;
    }

    if (marginColor != null) {
      params['highlightConfig']['marginColor'] = marginColor;
    }

    if (paddingColor != null) {
      params['highlightConfig']['paddingColor'] = paddingColor;
    }

    if (showInfo != null) {
      params['highlightConfig']['showInfo'] = showInfo;
    }

    return sendCommand('DOM.highlightNode', params: params);
  }

  Future highlightRect(int x, int y, int width, int height,
      {Rgba color, Rgba outlineColor}) {
    var params = <String, dynamic>{
      'x': x,
      'y': y,
      'width': width,
      'height': height
    };

    if (color != null) {
      params['color'] = color;
    }

    if (outlineColor != null) {
      params['outlineColor'] = outlineColor;
    }

    return sendCommand('DOM.highlightRect', params: params);
  }

  Future<int> moveTo(int nodeId, int targetNodeId,
      {int insertBeforeNodeId}) async {
    var params = {'nodeId': nodeId, 'targetNodeId': targetNodeId};

    if (insertBeforeNodeId != null) {
      params['insertBeforeNodeId'] = insertBeforeNodeId;
    }

    var resp = await sendCommand('DOM.moveTo', params: params);
    return resp.result['nodeId'] as int;
  }

  Future<int> querySelector(int nodeId, String selector) async {
    var resp = await sendCommand('DOM.querySelector',
        params: {'nodeId': nodeId, 'selector': selector});
    return resp.result['nodeId'] as int;
  }

  Future<List<int>> querySelectorAll(int nodeId, String selector) async {
    var resp = await sendCommand('DOM.querySelectorAll',
        params: {'nodeId': nodeId, 'selector': selector});
    return (resp.result['nodeIds'] as List).cast();
  }

  Future removeAttribute(int nodeId, String name) =>
      sendCommand('DOM.removeAttribute',
          params: {'nodeId': nodeId, 'name': name});

  Future removeNode(int nodeId) =>
      sendCommand('DOM.removeNode', params: {'nodeId': nodeId});

  Future requestChildNodes(int nodeId) =>
      sendCommand('DOM.requestChildNodes', params: {'nodeId': nodeId});

  Future<int> requestNode(String objectId) async {
    var resp =
        await sendCommand('DOM.requestNode', params: {'objectId': objectId});
    return resp.result['nodeId'] as int;
  }

  Future<WipRemoteObject> resolveNode(int nodeId, {String objectGroup}) async {
    var params = <String, dynamic>{'nodeId': nodeId};
    if (objectGroup != null) {
      params['objectGroup'] = objectGroup;
    }

    var resp = await sendCommand('DOM.resolveNode', params: params);
    return new WipRemoteObject(resp.result['object'] as Map<String, dynamic>);
  }

  Future setAttributeValue(int nodeId, String name, String value) =>
      sendCommand('DOM.setAttributeValue',
          params: {'nodeId': nodeId, 'name': name, 'value': value});

  Future setAttributesAsText(int nodeId, String text, {String name}) {
    var params = {'nodeId': nodeId, 'text': text};
    if (name != null) {
      params['name'] = name;
    }
    return sendCommand('DOM.setAttributeValue', params: params);
  }

  Future<int> setNodeName(int nodeId, String name) async {
    var resp = await sendCommand('DOM.setNodeName',
        params: {'nodeId': nodeId, 'name': name});
    return resp.result['nodeId'] as int;
  }

  Future setNodeValue(int nodeId, String value) =>
      sendCommand('DOM.setNodeValue',
          params: {'nodeId': nodeId, 'value': value});

  Future setOuterHtml(int nodeId, String outerHtml) =>
      sendCommand('DOM.setOuterHTML',
          params: {'nodeId': nodeId, 'outerHtml': outerHtml});

  Stream<AttributeModifiedEvent> get onAttributeModified => eventStream(
      'DOM.attributeModified',
      (WipEvent event) => new AttributeModifiedEvent(event));
  Stream<AttributeRemovedEvent> get onAttributeRemoved => eventStream(
      'DOM.attributeRemoved',
      (WipEvent event) => new AttributeRemovedEvent(event));
  Stream<CharacterDataModifiedEvent> get onCharacterDataModified => eventStream(
      'DOM.characterDataModified',
      (WipEvent event) => new CharacterDataModifiedEvent(event));
  Stream<ChildNodeCountUpdatedEvent> get onChildNodeCountUpdated => eventStream(
      'DOM.childNodeCountUpdated',
      (WipEvent event) => new ChildNodeCountUpdatedEvent(event));
  Stream<ChildNodeInsertedEvent> get onChildNodeInserted => eventStream(
      'DOM.childNodeInserted',
      (WipEvent event) => new ChildNodeInsertedEvent(event));
  Stream<ChildNodeRemovedEvent> get onChildNodeRemoved => eventStream(
      'DOM.childNodeRemoved',
      (WipEvent event) => new ChildNodeRemovedEvent(event));
  Stream<DocumentUpdatedEvent> get onDocumentUpdated => eventStream(
      'DOM.documentUpdated',
      (WipEvent event) => new DocumentUpdatedEvent(event));
  Stream<SetChildNodesEvent> get onSetChildNodes => eventStream(
      'DOM.setChildNodes', (WipEvent event) => new SetChildNodesEvent(event));
}

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

  int get nodeId => params['nodeId'] as int;
  String get name => params['name'] as String;
  String get value => params['value'] as String;
}

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

  int get nodeId => params['nodeId'] as int;
  String get name => params['name'] as String;
}

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

  int get nodeId => params['nodeId'] as int;
  String get characterData => params['characterData'] as String;
}

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

  int get nodeId => params['nodeId'] as int;
  int get childNodeCount => params['childNodeCount'] as int;
}

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

  int get parentNodeId => params['parentNodeId'] as int;
  int get previousNodeId => params['previousNodeId'] as int;
  Node _node;
  Node get node {
    if (_node == null) {
      _node = new Node(params['node'] as Map<String, dynamic>);
    }
    return _node;
  }
}

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

  int get parentNodeId => params['parentNodeId'] as int;
  int get nodeId => params['nodeId'] as int;
}

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

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

  int get nodeId => params['parentId'] as int;
  Iterable<Node> get nodes sync* {
    for (Map node in params['nodes']) {
      yield new Node(node as Map<String, dynamic>);
    }
  }

  String toString() => 'SetChildNodes $nodeId: $nodes';
}

/// The backend keeps track of which DOM nodes have been sent,
/// will only send each node once, and will only send events
/// for nodes that have been sent.
class Node {
  final Map<String, dynamic> _map;

  Node(this._map);

  Map<String, String> _attributes;
  Map<String, String> get attributes {
    if (_attributes == null && _map.containsKey('attributes')) {
      _attributes = _attributeListToMap((_map['attributes'] as List).cast());
    }
    return _attributes;
  }

  int get childNodeCount => _map['childNodeCount'] as int;

  List<Node> _children;
  List<Node> get children {
    if (_children == null && _map.containsKey('children')) {
      _children = new UnmodifiableListView((_map['children'] as List)
          .map((c) => new Node(c as Map<String, dynamic>)));
    }
    return _children;
  }

  Node get contentDocument {
    if (_map.containsKey('contentDocument')) {
      return new Node(_map['contentDocument'] as Map<String, dynamic>);
    }
    return null;
  }

  String get documentUrl => _map['documentURL'] as String;

  String get internalSubset => _map['internalSubset'] as String;

  String get localName => _map['localName'] as String;

  String get name => _map['name'] as String;

  int get nodeId => _map['nodeId'] as int;

  String get nodeName => _map['nodeName'] as String;

  int get nodeType => _map['nodeType'] as int;

  String get nodeValue => _map['nodeValue'] as String;

  String get publicId => _map['publicId'] as String;

  String get systemId => _map['systemId'] as String;

  String get value => _map['value'] as String;

  String get xmlVersion => _map['xmlVersion'] as String;

  String toString() => '$nodeName: $nodeId $attributes';
}

class Rgba {
  final int a;
  final int b;
  final int r;
  final int g;

  Rgba(this.r, this.g, this.b, [this.a]);

  Map toJson() {
    var json = {'r': r, 'g': g, 'b': b};
    if (a != null) {
      json['a'] = a;
    }
    return json;
  }
}

Map<String, String> _attributeListToMap(List<String> attrList) {
  var attributes = <String, String>{};
  for (int i = 0; i < attrList.length; i += 2) {
    attributes[attrList[i]] = attrList[i + 1];
  }
  return new UnmodifiableMapView(attributes);
}
