package propagation.impl;

import propagation.Node;
import propagation.PropagationRule;
import propagation.StateItem;

import java.util.List;

public abstract class AbstractPropagtionRule implements PropagationRule {
   public void changeState(Node node, long itemId, long state) {
      StateItem target = node.findStateItem(itemId);
      if (target == null) {
         System.out.println("[Error] StateItem not found. : " + node + ":"
                 + itemId);
         return;
      }

      if (StateItem.STATE_CHANGED == target.setState(state)) {
         summaryUpperPropagate(node);
      }
   }

   protected void upperPropagate(Node node) {
      // propagate to parent node.
      Node parentNode = (Node) node.getParentNode();
      if (parentNode != null) {
         PropagationRule parentRule = parentNode.getPropagationRule();
         parentRule.summaryUpperPropagate(parentNode);
      }

      // propagate to upper nodes.
      List upperNodes = node.getUpperNodes();
      int size = upperNodes.size();
      for (int index = 0; index < size; index++) {
         Node upperNode = (Node) upperNodes.get(index);
         PropagationRule upperRule = upperNode.getPropagationRule();
         upperRule.summaryUpperPropagate(upperNode);
      }
   }

   protected boolean isClear(StateItem item) {
      long state = item.getState();
      if ((state % 10) == 0) {
         return true;
      } else {
         return false;
      }
   }

   protected long getSeverity(StateItem item) {
      long state = item.getState();
      long severity = 0;
      if (true == isSummaryItem(item)) {
         severity = state % 1000;
      } else {
         severity = (state % 1000) / 10;
      }

      return severity;
   }

   protected boolean isSummaryItem(StateItem item) {
      long state = item.getState();
      long summaryDigit = (state / 1000) % 10;

      if (summaryDigit == 2) {
         return true;
      } else {
         return false;
      }
   }

   protected long updateMaxSeverity(long maxSeverity, StateItem stateItem) {
      if (false == isClear(stateItem)) {
         long severity = getSeverity(stateItem);
         if (severity > maxSeverity) {
            maxSeverity = severity;
         }
      }

      return maxSeverity;
   }
}
