// 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<RemoteObject> 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 RemoteObject(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.json));

  Stream<AttributeRemovedEvent> get onAttributeRemoved => eventStream(
      'DOM.attributeRemoved',
      (WipEvent event) => new AttributeRemovedEvent(event.json));

  Stream<CharacterDataModifiedEvent> get onCharacterDataModified => eventStream(
      'DOM.characterDataModified',
      (WipEvent event) => new CharacterDataModifiedEvent(event.json));

  Stream<ChildNodeCountUpdatedEvent> get onChildNodeCountUpdated => eventStream(
      'DOM.childNodeCountUpdated',
      (WipEvent event) => new ChildNodeCountUpdatedEvent(event.json));

  Stream<ChildNodeInsertedEvent> get onChildNodeInserted => eventStream(
      'DOM.childNodeInserted',
      (WipEvent event) => new ChildNodeInsertedEvent(event.json));

  Stream<ChildNodeRemovedEvent> get onChildNodeRemoved => eventStream(
      'DOM.childNodeRemoved',
      (WipEvent event) => new ChildNodeRemovedEvent(event.json));

  Stream<DocumentUpdatedEvent> get onDocumentUpdated => eventStream(
      'DOM.documentUpdated',
      (WipEvent event) => new DocumentUpdatedEvent(event.json));

  Stream<SetChildNodesEvent> get onSetChildNodes => eventStream(
      'DOM.setChildNodes',
      (WipEvent event) => new SetChildNodesEvent(event.json));
}

class AttributeModifiedEvent extends WipEvent {
  AttributeModifiedEvent(Map<String, dynamic> json) : super(json);

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

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

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

class AttributeRemovedEvent extends WipEvent {
  AttributeRemovedEvent(Map<String, dynamic> json) : super(json);

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

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

class CharacterDataModifiedEvent extends WipEvent {
  CharacterDataModifiedEvent(Map<String, dynamic> json) : super(json);

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

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

class ChildNodeCountUpdatedEvent extends WipEvent {
  ChildNodeCountUpdatedEvent(Map<String, dynamic> json) : super(json);

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

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

class ChildNodeInsertedEvent extends WipEvent {
  ChildNodeInsertedEvent(Map<String, dynamic> json) : super(json);

  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 WipEvent {
  ChildNodeRemovedEvent(Map<String, dynamic> json) : super(json);

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

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

class DocumentUpdatedEvent extends WipEvent {
  DocumentUpdatedEvent(Map<String, dynamic> json) : super(json);
}

class SetChildNodesEvent extends WipEvent {
  SetChildNodesEvent(Map<String, dynamic> json) : super(json);

  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);
}
