// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library services.src.index.store.store_memory_node_manager;

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

import 'package:analysis_services/src/index/store/codec.dart';
import 'package:analysis_services/src/index/store/split_store.dart';
import 'package:analyzer/src/generated/engine.dart';


class MemoryNodeManager implements NodeManager {
  StringCodec _stringCodec = new StringCodec();
  ContextCodec _contextCodec = new ContextCodec();
  ElementCodec _elementCodec;
  RelationshipCodec _relationshipCodec;

  int _locationCount = 0;
  final Map<String, int> _nodeLocationCounts = new HashMap<String, int>();
  final Map<String, IndexNode> _nodes = new HashMap<String, IndexNode>();

  MemoryNodeManager() {
    _elementCodec = new ElementCodec(_stringCodec);
    _relationshipCodec = new RelationshipCodec(_stringCodec);
  }

  @override
  ContextCodec get contextCodec {
    return _contextCodec;
  }

  @override
  ElementCodec get elementCodec {
    return _elementCodec;
  }

  @override
  int get locationCount {
    return _locationCount;
  }

  @override
  StringCodec get stringCodec {
    return _stringCodec;
  }

  @override
  void clear() {
    _nodes.clear();
  }

  int getLocationCount(String name) {
    int locationCount = _nodeLocationCounts[name];
    return locationCount != null ? locationCount : 0;
  }

  @override
  Future<IndexNode> getNode(String name) {
    return new Future.value(_nodes[name]);
  }

  bool isEmpty() {
    for (IndexNode node in _nodes.values) {
      Map<RelationKeyData, List<LocationData>> relations = node.relations;
      if (!relations.isEmpty) {
        return false;
      }
    }
    return true;
  }

  @override
  IndexNode newNode(AnalysisContext context) {
    return new IndexNode(context, elementCodec, _relationshipCodec);
  }

  @override
  void putNode(String name, IndexNode node) {
    // update location count
    {
      _locationCount -= getLocationCount(name);
      int nodeLocationCount = node.locationCount;
      _nodeLocationCounts[name] = nodeLocationCount;
      _locationCount += nodeLocationCount;
    }
    // remember the node
    _nodes[name] = node;
  }

  @override
  void removeNode(String name) {
    _nodes.remove(name);
  }
}
