from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from utilities import Util
from HealthAction import HealthAction
from CustomHealthAction import CustomHealthAction
from AgeCondition import AgeCondition
from WorkloadCondition import WorkloadCondition
from MemoryCondition import MemoryCondition
from ResponseCondition import ResponseCondition
from StuckRequestCondition import StuckRequestCondition
from StormDrainCondition import StormDrainCondition
from MemoryLeakAlgorithm import MemoryLeakAlgorithm
from GCPercentageCondition import GCPercentageCondition
from TargetMembership import TargetMembership

__name_att__ = "websphere.healthclass.name"

def export(objid, parentcontainmentpath, parentrespath):

  name = Util.getRequiredAttribute(objid, "name", 'HealthClass');

  containmentpath = "%(parentconpath)sHealthClass:%(name)s/" % {'parentconpath':parentcontainmentpath, 'name':name }
  if not containmentpath.startswith("/"):
    containmentpath = "/" + containmentpath;

  dict = _export(objid, parentrespath);
  dict['conpath'] = containmentpath;
  return dict

def _export(objid, parentrespath):
  Util.pushPathElement('HealthClass')

  name = Util.getRequiredAttribute(objid, "name", 'HealthClass');


  if parentrespath == "/":
    parentrespath = "";
  respath = "%(parentrespath)s/%(name)s" % { 'parentrespath':parentrespath, 'name':name }
  if not respath.startswith("/"):
    respath = "/" + respath;

  exportedObject = JSONObject();
  exportedObject.put("name", name);
  exportedObject.put("path", respath);
  exportedObject.put("teamMappings", JSONArray());
  exportedObject.put("inheritTeam", "true");
  exportedObject.put("description", "Discovered WebSphereHealthClass");
  exportedObject.put("roleName", "WebSphereHealthClass");

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.healthclass.reactionmode", objid, "reactionMode","HealthClass");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.healthclass.name", objid, "name","HealthClass");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.healthclass.description", objid, "description","HealthClass");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};

  i = 0;
  # returns HealthActions and CustomHealthActions. Need to handle separately
  healthActions = HealthAction.getHealthActions(objid);
  if healthActions != None and len(healthActions) > 0:
    for healthAction in healthActions:
      if len(healthAction) > 0 and healthAction.find("#HealthAction") != -1:
        returndict = Util.createTypeFolder(respath, "HealthAction", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          Util.addFromExport(extraObjects, returndict['object']);
        Util.addAllFromExport(extraObjects, HealthAction._export(healthAction, currespath, "HealthAction%s" % i));
        i = i + 1;

  i = 0;
  if healthActions != None and len(healthActions) > 0:
    for healthAction in healthActions:
      if len(healthAction) > 0 and healthAction.find("#CustomHealthAction") != -1:
        returndict = Util.createTypeFolder(respath, "CustomHealthAction", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          Util.addFromExport(extraObjects, returndict['object']);
        Util.addAllFromExport(extraObjects, CustomHealthAction._export(healthAction, currespath, "CustomHealthAction%s" % i));
        i = i + 1;

  ageConditions = AgeCondition.getAgeCondition(objid);
  if ageConditions is not None and len(ageConditions) > 1:
    raise Exception("More than one AgeCondition was returned for " + str(objid));
  if ageConditions is not None and len(ageConditions) > 0:
    for ageCondition in ageConditions:
      returndict = Util.createTypeFolder(respath, "AgeCondition", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, AgeCondition._export(ageCondition, currespath, "Age Condition"));

  workloadConditions = WorkloadCondition.getWorkloadCondition(objid);
  if workloadConditions is not None and len(workloadConditions) > 1:
    raise Exception("More than one WorkloadCondition was returned for " + str(objid));
  if workloadConditions is not None and len(workloadConditions) > 0:
    for workloadCondition in workloadConditions:
      returndict = Util.createTypeFolder(respath, "WorkloadCondition", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, WorkloadCondition._export(workloadCondition, currespath, "Workload Condition"));

  memoryConditions = MemoryCondition.getMemoryCondition(objid);
  if memoryConditions is not None and len(memoryConditions) > 1:
    raise Exception("More than one MemoryCondition was returned for " + str(objid));
  if memoryConditions is not None and len(memoryConditions) > 0:
    for memoryCondition in memoryConditions:
      returndict = Util.createTypeFolder(respath, "MemoryCondition", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, MemoryCondition._export(memoryCondition, currespath, "Memory Condition"));

  responseConditions = ResponseCondition.getResponseCondition(objid);
  if responseConditions is not None and len(responseConditions) > 1:
    raise Exception("More than one ResponseCondition was returned for " + str(objid));
  if responseConditions is not None and len(responseConditions) > 0:
    for responseCondition in responseConditions:
      returndict = Util.createTypeFolder(respath, "ResponseCondition", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, ResponseCondition._export(responseCondition, currespath, "Response Condition"));

  stuckRequestConditions = StuckRequestCondition.getStuckRequestCondition(objid);
  if stuckRequestConditions is not None and len(stuckRequestConditions) > 1:
    raise Exception("More than one StuckRequestCondition was returned for " + str(objid));
  if stuckRequestConditions is not None and len(stuckRequestConditions) > 0:
    for stuckRequestCondition in stuckRequestConditions:
      returndict = Util.createTypeFolder(respath, "StuckRequestCondition", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, StuckRequestCondition._export(stuckRequestCondition, currespath, "Stuck Request Condition"));

  stormDrainConditions = StormDrainCondition.getStormDrainCondition(objid);
  if stormDrainConditions is not None and len(stormDrainConditions) > 1:
    raise Exception("More than one StormDrainCondition was returned for " + str(objid));
  if stormDrainConditions is not None and len(stormDrainConditions) > 0:
    for stormDrainCondition in stormDrainConditions:
      returndict = Util.createTypeFolder(respath, "StormDrainCondition", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, StormDrainCondition._export(stormDrainCondition, currespath, "Storm Drain Condition"));

  gcPercentageConditions = GCPercentageCondition.getGCPercentageCondition(objid);
  if gcPercentageConditions is not None and len(gcPercentageConditions) > 1:
    raise Exception("More than one GCPercentageCondition was returned for " + str(objid));
  if gcPercentageConditions is not None and len(gcPercentageConditions) > 0:
    for gcPercentageCondition in gcPercentageConditions:
      returndict = Util.createTypeFolder(respath, "GCPercentageCondition", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, GCPercentageCondition._export(gcPercentageCondition, currespath, "GC Percentage Condition"));

  memoryLeakAlgorithms = MemoryLeakAlgorithm.getMemoryLeakAlgorithm(objid);
  if memoryLeakAlgorithms is not None and len(memoryLeakAlgorithms) > 1:
    raise Exception("More than one MemoryLeakAlgorithm was returned for " + str(objid));
  if memoryLeakAlgorithms is not None and len(memoryLeakAlgorithms) > 0:
    for memoryLeakAlgorithm in memoryLeakAlgorithms:
      returndict = Util.createTypeFolder(respath, "MemoryLeakAlgorithm", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, MemoryLeakAlgorithm._export(memoryLeakAlgorithm, currespath, "Workload Condition"));

  i = 0;
  targetMemberships = Util.parseConfigIdListAttribute(objid, 'targetMemberships', "HealthClass");
  for targetMembership in targetMemberships:
    if len(targetMembership) > 0:
      returndict = Util.createTypeFolder(respath, "TargetMembership", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, TargetMembership._export(targetMembership, currespath, "TargetMembership%s" % i));
      i = i + 1;

  if len(extraObjects) != 0:
    result['extraObjects'] = extraObjects;
  Util.popPathElement('HealthClass');
  return result;

def doImportPartial(containmentpath, roleName, jsonobject):
  return doImport(containmentpath, roleName, jsonobject);

def doImport(containmentpath, roleName, jsonobject):
  if not jsonobject.has("roleProperties"):
    raise Exception("HealthClass resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");
  if not roleProperties.has("websphere.healthclass.name"):
    raise Exception("Resource role properties does not contain websphere.healthclass.name!");

  objid = Util.getid(containmentpath);
  if objid == None or len(objid) == 0:
    if Util.__removePartialConfig__ == "false":
      index = containmentpath.rindex('/',0,len(containmentpath)-2)+1;
      parentconpath = containmentpath[0:index];
      parentid = Util.getid(parentconpath);
      if parentid == None or len(parentid) == 0:
        raise Exception("Parent does not exist to create HealthClass on.");
      objid = create(parentid, jsonobject);
  else:
    if Util.__removePartialConfig__ == "true":
      Util.removePartialApply(objid);
      objid = None;
    else:
      update(objid,jsonobject);
  return objid;



def create(parentid, jsonobject):
  Util.pushPathElement('HealthClass')
  if not jsonobject.has("roleProperties"):
    raise Exception("HealthClass resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");

  if not roleProperties.has("websphere.healthclass.name"):
    raise Exception("Resource role properties does not contain websphere.healthclass.name!");

  properties = [];
  Util.addIfNotNone(properties, "reactionMode", roleProperties.optString("websphere.healthclass.reactionmode", None));
  Util.addIfNotNone(properties, "name", roleProperties.optString("websphere.healthclass.name", None));
  Util.addIfNotNone(properties, "description", roleProperties.optString("websphere.healthclass.description", None));
  print "Creating HealthClass with attributes";
  for prop in properties:
    print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };
  objid = Util.create("HealthClass", parentid, properties);

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      if currole == "WebSphereHealthAction":
        HealthAction.create(objid, curjsonobject);
      elif currole == "WebSphereCustomHealthAction":
        CustomHealthAction.create(objid, curjsonobject);
      elif currole == "WebSphereAgeCondition":
        AgeCondition.create(objid, curjsonobject);
      elif currole == "WebSphereWorkloadCondition":
        WorkloadCondition.create(objid, curjsonobject);
      elif currole == "WebSphereMemoryCondition":
        MemoryCondition.create(objid, curjsonobject);
      elif currole == "WebSphereResponseCondition":
        ResponseCondition.create(objid, curjsonobject);
      elif currole == "WebSphereStuckRequestCondition":
        StuckRequestCondition.create(objid, curjsonobject);
      elif currole == "WebSphereStormDrainCondition":
        StormDrainCondition.create(objid, curjsonobject);
      elif currole == "WebSphereMemoryLeakAlgorithm":
        MemoryLeakAlgorithm.create(objid, curjsonobject);
      elif currole == "WebSphereTargetMembership":
        TargetMembership.create(objid, curjsonobject);
      elif currole == "WebSphereGCPercentageCondition":
        GCPercentageCondition.create(objid, curjsonobject);

  Util.popPathElement('HealthClass');
  return objid;

def update(objid,jsonobject):
  Util.pushPathElement('HealthClass')
  if not jsonobject.has("roleProperties"):
    raise Exception("HealthClass resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");

  if not roleProperties.has("websphere.healthclass.name"):
    raise Exception("Resource role properties does not contain websphere.healthclass.name!");

  atts = [];
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.healthclass.reactionmode", None), "reactionMode","HealthClass");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.healthclass.name", None), "name","HealthClass");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.healthclass.description", None), "description","HealthClass");
  if len(atts) != 0:
    print "Modifying HealthClass with attributes:"
    for prop in atts:
      print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };

    Util.modify(objid, atts);
  else:   
    print "HealthClass configuration up to date.";

  # returns HealthActions and CustomHealthActions
  healthActions = HealthAction.getHealthActions(objid);
  if healthActions != None and len(healthActions) > 0:
    for healthAction in healthActions:
      if len(healthAction) > 0:
        Util.remove(healthAction);

  targetMemberships = Util.parseConfigIdListAttribute(objid, 'targetMemberships', "HealthClass");
  for targetMembership in targetMemberships:
    if len(targetMembership) > 0:
      Util.remove(targetMembership);

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      if currole == "WebSphereHealthAction":
        HealthAction.create(objid, curjsonobject);
      elif currole == "WebSphereCustomHealthAction":
        CustomHealthAction.create(objid, curjsonobject);
      elif currole == "WebSphereAgeCondition":
        AgeCondition.create(objid, curjsonobject);
      elif currole == "WebSphereWorkloadCondition":
        WorkloadCondition.create(objid, curjsonobject);
      elif currole == "WebSphereMemoryCondition":
        MemoryCondition.create(objid, curjsonobject);
      elif currole == "WebSphereResponseCondition":
        ResponseCondition.create(objid, curjsonobject);
      elif currole == "WebSphereStuckRequestCondition":
        StuckRequestCondition.create(objid, curjsonobject);
      elif currole == "WebSphereStormDrainCondition":
        StormDrainCondition.create(objid, curjsonobject);
      elif currole == "WebSphereMemoryLeakAlgorithm":
        MemoryLeakAlgorithm.create(objid, curjsonobject);
      elif currole == "WebSphereTargetMembership":
        TargetMembership.create(objid, curjsonobject);
      elif currole == "WebSphereGCPercentageCondition":
        GCPercentageCondition.create(objid, curjsonobject);

  Util.popPathElement('HealthClass');
