package org.rabix.engine.store.lru.dag;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.configuration.Configuration;
import org.rabix.bindings.model.dag.DAGContainer;
import org.rabix.bindings.model.dag.DAGNode;
import org.rabix.common.helper.ChecksumHelper;
import org.rabix.common.helper.ChecksumHelper.HashAlgorithm;
import org.rabix.common.helper.JSONHelper;
import org.rabix.common.json.BeanSerializer;
import org.rabix.engine.store.lru.LRUCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;

public class DAGCache extends LRUCache<String, DAGNode> {
  
  private final Logger logger = LoggerFactory.getLogger(DAGCache.class);
  private final static String CACHE_NAME = "DAGCache";
  private static int DEFAULT_CACHE_SIZE = 16;
  
  @Inject
  public DAGCache(Configuration configuration) {
    super(CACHE_NAME, configuration.getInteger("cache.dag.size", DEFAULT_CACHE_SIZE));
    logger.debug("{} initialized with size={}", CACHE_NAME, getCacheSize());
  }
  
  public DAGCache(int cacheSize) {
    super(CACHE_NAME, cacheSize);
  }
  
  public DAGNode get(String id, UUID rootId, String dagHash) {
    DAGNode res = null;
    res = get(dagHash);
    if(res != null) {
      logger.debug("DAGNode rootId={}, id={} found in cache", rootId, id);
      logger.debug("Cache size={}", size());
    }
    return res != null ? getIdFromDAG(id, res) : null;    
  }
  
  public String put(DAGNode dagNode, UUID rootId) {
    String dagHash = hashDagNode(dagNode);
    put(dagHash, dagNode);
    return dagHash;
  }
  
  public DAGNode getIdFromDAG(String id, DAGNode node) {
    Map<String, DAGNode> allNodes = new HashMap<String, DAGNode>();
    populateNodes(node, allNodes);
    return allNodes.get(id);
  }
  
  private void populateNodes(DAGNode node, Map<String, DAGNode> allNodes) {
    allNodes.put(node.getId(), node);
    if (node instanceof DAGContainer) {
      for (DAGNode child : ((DAGContainer) node).getChildren()) {
        populateNodes(child, allNodes);
      }
    }
  }
  
  public static String hashDagNode(DAGNode dagNode) {
    String dagText = BeanSerializer.serializeFull(dagNode);
    String cachedSortedDAGText = JSONHelper.writeSortedWithoutIdentation(JSONHelper.readJsonNode(dagText));
    String cachedDAGHash = ChecksumHelper.checksum(cachedSortedDAGText, HashAlgorithm.SHA1);
    return cachedDAGHash;
  }
  
}

@@ -45,73 +45,34 @@
 ort 
-java.util.HashMap;%0Aimport java.util.Map;%0Aimport java.util.UUID
+com.google.inject.Inject
 ;%0A
-%0A
 impo
@@ -526,32 +526,70 @@
 ort 
-com.google.inject.Inject
+java.util.HashMap;%0Aimport java.util.Map;%0Aimport java.util.UUID
 ;%0A%0Ap
@@ -645,19 +645,17 @@
 Node%3E %7B%0A
-  
 %0A
+
   privat
@@ -820,19 +820,17 @@
 E = 16;%0A
-  
 %0A
+
   @Injec
@@ -1044,27 +1044,25 @@
 ize());%0A  %7D%0A
-  
 %0A
+
   public DAG
@@ -1118,27 +1118,25 @@
 eSize);%0A  %7D%0A
-  
 %0A
+
   public DAG
@@ -1238,156 +1238,8 @@
 h);%0A
-    if(res != null) %7B%0A      logger.debug(%22DAGNode rootId=%7B%7D, id=%7B%7D found in cache%22, rootId, id);%0A      logger.debug(%22Cache size=%7B%7D%22, size());%0A    %7D%0A
     
@@ -1292,20 +1292,14 @@
 ull;
-    
 %0A  %7D%0A
-  
 %0A
+
   pu
@@ -1436,27 +1436,25 @@
 agHash;%0A  %7D%0A
-  
 %0A
+
   public DAG
@@ -1634,19 +1634,17 @@
 d);%0A  %7D%0A
-  
 %0A
+
   privat
@@ -1913,19 +1913,17 @@
   %7D%0A  %7D%0A
-  
 %0A
+
   public
@@ -2259,13 +2259,11 @@
 sh;%0A  %7D%0A
-  
 %0A%7D%0A

remove some log