// 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.

library wip.dom_model;

import 'dart:async' show EventSink, Future, Stream, StreamTransformer;
import 'dart:collection' show UnmodifiableListView, UnmodifiableMapView;
import 'dart:mirrors' show reflect;

import 'package:logging/logging.dart' show Logger;

import 'webkit_inspection_protocol.dart'
    show
        AttributeModifiedEvent,
        AttributeRemovedEvent,
        CharacterDataModifiedEvent,
        ChildNodeCountUpdatedEvent,
        ChildNodeInsertedEvent,
        ChildNodeRemovedEvent,
        DocumentUpdatedEvent,
        Node,
        SetChildNodesEvent,
        WipDom,
        WipEvent;

/// Implementation of WipDom that maintains and updates a model of the DOM
/// based on incoming events.
class WipDomModel implements WipDom {
  static final _log = new Logger('WipDomModel');

  final WipDom _dom;

  Map<int, _Node> _nodeCache = {};
  Future<_Node> _root;

  Stream<AttributeModifiedEvent> onAttributeModified;
  Stream<AttributeRemovedEvent> onAttributeRemoved;
  Stream<CharacterDataModifiedEvent> onCharacterDataModified;
  Stream<ChildNodeCountUpdatedEvent> onChildNodeCountUpdated;
  Stream<ChildNodeInsertedEvent> onChildNodeInserted;
  Stream<ChildNodeRemovedEvent> onChildNodeRemoved;
  Stream<DocumentUpdatedEvent> onDocumentUpdated;
  Stream<SetChildNodesEvent> onSetChildNodes;

  WipDomModel(this._dom) {
    onAttributeModified = new StreamTransformer.fromHandlers(
        handleData: _onAttributeModified).bind(_dom.onAttributeModified)
      ..listen(_logEvent);
    onAttributeRemoved = new StreamTransformer.fromHandlers(
        handleData: _onAttributeRemoved).bind(_dom.onAttributeRemoved)
      ..listen(_logEvent);
    onCharacterDataModified = new StreamTransformer.fromHandlers(
        handleData: _onCharacterDataModified).bind(_dom.onCharacterDataModified)
      ..listen(_logEvent);
    onChildNodeCountUpdated = new StreamTransformer.fromHandlers(
        handleData: _onChildNodeCountUpdated).bind(_dom.onChildNodeCountUpdated)
      ..listen(_logEvent);
    onChildNodeInserted = new StreamTransformer.fromHandlers(
        handleData: _onChildNodeInserted).bind(_dom.onChildNodeInserted)
      ..listen(_logEvent);
    onChildNodeRemoved = new StreamTransformer.fromHandlers(
        handleData: _onChildNodeRemoved).bind(_dom.onChildNodeRemoved)
      ..listen(_logEvent);
    onDocumentUpdated = new StreamTransformer.fromHandlers(
        handleData: _onDocumentUpdated).bind(_dom.onDocumentUpdated)
      ..listen(_logEvent);
    onSetChildNodes = new StreamTransformer.fromHandlers(
        handleData: _onSetChildNodes).bind(_dom.onSetChildNodes)
      ..listen(_logEvent);
  }

  _logEvent(WipEvent event) {
    _log.finest('Event $event');
  }

  _onAttributeModified(
      AttributeModifiedEvent event, EventSink<AttributeModifiedEvent> sink) {
    var node = _getOrCreateNode(event.nodeId);
    node._attributes[event.name] = event.value;
    sink.add(event);
  }

  _onAttributeRemoved(
      AttributeRemovedEvent event, EventSink<AttributeRemovedEvent> sink) {
    var node = _getOrCreateNode(event.nodeId);
    node._attributes.remove(event.name);
    sink.add(event);
  }

  _onCharacterDataModified(CharacterDataModifiedEvent event,
      EventSink<CharacterDataModifiedEvent> sink) {
    var node = _getOrCreateNode(event.nodeId);
    node._nodeValue = event.characterData;
    sink.add(event);
  }

  _onChildNodeCountUpdated(ChildNodeCountUpdatedEvent event,
      EventSink<ChildNodeCountUpdatedEvent> sink) {
    var node = _getOrCreateNode(event.nodeId);
    node._childNodeCount = event.childNodeCount;
    sink.add(event);
  }

  _onChildNodeInserted(
      ChildNodeInsertedEvent event, EventSink<ChildNodeInsertedEvent> sink) {
    var parent = _getOrCreateNode(event.parentNodeId);
    int index = 0;
    if (event.previousNodeId != null) {
      index =
          parent._children.indexOf(_getOrCreateNode(event.previousNodeId)) + 1;
    }
    var node = _getOrCreateNodeFromNode(event.node);
    parent._children.insert(index, node);
    parent._childNodeCount = parent._children.length;
    sink.add(event);
  }

  _onChildNodeRemoved(
      ChildNodeRemovedEvent event, EventSink<ChildNodeRemovedEvent> sink) {
    var parent = _getOrCreateNode(event.parentNodeId);
    var node = _nodeCache.remove(event.nodeId);
    parent._children.remove(node);
    parent._childNodeCount = parent._children.length;
    sink.add(event);
  }

  _onDocumentUpdated(
      DocumentUpdatedEvent event, EventSink<DocumentUpdatedEvent> sink) {
    _nodeCache.clear();
    _root = null;
    sink.add(event);
  }

  _onSetChildNodes(
      SetChildNodesEvent event, EventSink<SetChildNodesEvent> sink) {
    var parent = _getOrCreateNode(event.nodeId);
    parent._children =
        event.nodes.map(_getOrCreateNodeFromNode).toList(growable: true);
    parent._childNodeCount = parent._children.length;
    sink.add(event);
  }

  @override
  Future<Map<String, String>> getAttributes(int nodeId) async {
    Map<String, String> attributes = await _dom.getAttributes(nodeId);
    var node = _getOrCreateNode(nodeId);
    node._attributes = new Map.from(attributes);
    return attributes;
  }

  /// Unlike the standard [WipDom.getDocument] call, this will not
  /// reset the internal state of the debugger remote end when called
  /// multiple times on the same page.
  @override
  Future<Node> getDocument() {
    if (_root == null) {
      _root = _dom.getDocument().then((n) => _getOrCreateNodeFromNode(n));
    }
    return _root;
  }

  _Node _getOrCreateNode(int nodeId) =>
      _nodeCache.putIfAbsent(nodeId, () => new _Node(nodeId));

  _Node _getOrCreateNodeFromNode(Node src) {
    try {
      var node = _getOrCreateNode(src.nodeId);
      if (src.attributes != null) {
        node._attributes = new Map.from(src.attributes);
      }
      if (src.children != null) {
        node._children =
            src.children.map(_getOrCreateNodeFromNode).toList(growable: true);
      }
      node._childNodeCount = src.childNodeCount;
      if (src.contentDocument != null) {
        node._contentDocument = _getOrCreateNodeFromNode(src.contentDocument);
      }
      node._documentUrl = src.documentUrl;
      node._internalSubset = src.internalSubset;
      node._localName = src.localName;
      node._name = src.name;
      node._nodeName = src.nodeName;
      node._nodeType = src.nodeType;
      node._nodeValue = src.nodeValue;
      node._publicId = src.publicId;
      node._systemId = src.systemId;
      node._value = src.value;
      node._xmlVersion = src.xmlVersion;
      return node;
    } catch (e, s) {
      _log.severe('Error parsing: $src.nodeId', e, s);
      rethrow;
    }
  }

  noSuchMethod(Invocation invocation) => reflect(_dom).delegate(invocation);
}

class _Node implements Node {
  Map<String, String> _attributes;
  @override
  Map<String, String> get attributes =>
      _attributes != null ? new UnmodifiableMapView(_attributes) : null;

  int _childNodeCount;
  @override
  int get childNodeCount => _childNodeCount;

  List<_Node> _children;
  @override
  List<Node> get children =>
      _children != null ? new UnmodifiableListView(_children) : null;

  _Node _contentDocument;
  @override
  Node get contentDocument => _contentDocument;

  String _documentUrl;
  @override
  String get documentUrl => _documentUrl;

  String _internalSubset;
  @override
  String get internalSubset => _internalSubset;

  String _localName;
  @override
  String get localName => _localName;

  String _name;
  @override
  String get name => _name;

  @override
  final int nodeId;

  String _nodeName;
  @override
  String get nodeName => _nodeName;

  int _nodeType;
  @override
  int get nodeType => _nodeType;

  String _nodeValue;
  @override
  String get nodeValue => _nodeValue;

  String _publicId;
  @override
  String get publicId => _publicId;

  String _systemId;
  @override
  String get systemId => _systemId;

  String _value;
  @override
  String get value => _value;

  String _xmlVersion;
  @override
  String get xmlVersion => _xmlVersion;

  _Node(this.nodeId);

  Map toJson() => _toJsonInternal(new Set());

  Map _toJsonInternal(Set visited) {
    var map = {
      'localName': localName,
      'nodeId': nodeId,
      'nodeName': nodeName,
      'nodeType': nodeType,
      'nodeValue': nodeValue
    };
    if (visited.add(nodeId)) {
      if (attributes != null && attributes.isNotEmpty) {
        map['attributes'] = flattenAttributesMap(attributes);
      }
      if (childNodeCount != null) {
        map['childNodeCount'] = childNodeCount;
      }
      if (children != null && children.isNotEmpty) {
        var newChildren = [];
        children.forEach((child) {
          if (child != null) {
            newChildren.add(child._toJsonInternal(visited));
          }
        });
        map['children'] = newChildren;
      }
      if (_contentDocument != null) {
        map['contentDocument'] = _contentDocument._toJsonInternal(visited);
      }
      if (documentUrl != null) {
        map['documentUrl'] = documentUrl;
      }
      if (internalSubset != null) {
        map['internalSubset'] = internalSubset;
      }
      if (name != null) {
        map['name'] = name;
      }
      if (publicId != null) {
        map['publicId'] = publicId;
      }
      if (systemId != null) {
        map['systemId'] = systemId;
      }
      if (value != null) {
        map['value'] = value;
      }
      if (xmlVersion != null) {
        map['xmlVersion'] = xmlVersion;
      }
    }
    return map;
  }
}

List<String> flattenAttributesMap(Map<String, String> attributes) {
  var result = <String>[];
  attributes.forEach((k, v) {
    if (k != null) {
      result
        ..add(k)
        ..add(v);
    }
  });
  return result;
}
