from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;

from FileTransferService import FileTransferService
from ConfigSynchronizationService import ConfigSynchronizationService
from Service import Service
from EndPoint import EndPoint
from Component import Component
from Property import Property
from utilities import Util
from StateManageable import StateManageable

__name_att__ = None;

def _export(objid, parentrespath, name = ""):
  Util.pushPathElement('NodeAgent')


  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 WebSphereNodeAgent");
  exportedObject.put("roleName", "WebSphereNodeAgent");

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.nodeagent.name", objid, "name","NodeAgent");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};

  extraObjects = Property.exportProperties(objid, respath, extraObjects, typeFolders, 'properties',"NodeAgent");
  extraObjects = Component.exportComponents(objid, respath, extraObjects, typeFolders, 'components', "NodeAgent");
  extraObjects = Service.exportServices(objid, respath, extraObjects, typeFolders, 'services', "NodeAgent");

  filetransferservice = Util.getOptionalAttribute(objid, 'fileTransferService', "NodeAgent");
  if filetransferservice is not None and len(filetransferservice) > 0:
    returndict = Util.createTypeFolder(respath, "FileTransferService", typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, FileTransferService._export(filetransferservice, currespath, "FileTransferService"));

  filesynchronizationservice = Util.getOptionalAttribute(objid, 'fileSynchronizationService', "NodeAgent");
  if filesynchronizationservice is not None and len(filesynchronizationservice) > 0:
    returndict = Util.createTypeFolder(respath, "ConfigSynchronizationService", typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, ConfigSynchronizationService._export(filesynchronizationservice, currespath, "ConfigSynchronizationService"));

  nodediscoveryaddress = Util.getOptionalAttribute(objid, 'NODE_DISCOVERY_ADDRESS', "NodeAgent");
  returndict = Util.createTypeFolder(respath, "EndPoint", typeFolders);
  currespath = returndict['path'];
  if returndict.has_key('object'):
    Util.addFromExport(extraObjects, returndict['object']);
  Util.addAllFromExport(extraObjects, EndPoint._export(nodediscoveryaddress, currespath, "NODE_DISCOVERY_ADDRESS"));

  stateManagement = Util.getRequiredAttribute(objid, 'stateManagement',"NodeAgent");
  if stateManagement is not None and len(stateManagement) > 0:
    returndict = Util.createTypeFolder(respath, "StateManageable", typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, StateManageable._export(stateManagement, currespath, "StateManageable"));    
  
  if len(extraObjects) != 0:
    result['extraObjects'] = extraObjects;
  Util.popPathElement('NodeAgent');
  return result;



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

  roleProperties = jsonobject.getJSONObject("roleProperties");

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

  Component.removeComponents(objid, 'components', "NodeAgent");
  Property.removeProperties(objid, 'properties',"NodeAgent");
  Service.removeServices(objid, 'services', "NodeAgent");

  stateManagement = Util.getRequiredAttribute(objid, 'stateManagement',"NodeAgent");
  if stateManagement is not None and len(stateManagement) > 0:
    Util.remove(stateManagement);    

  #filetransferservice = Util.getOptionalAttribute(objid, 'fileTransferService', "NodeAgent");
  #filesynchronizationservice = Util.getOptionalAttribute(objid, 'fileSynchronizationService', "NodeAgent");

  #if filetransferservice is not None and len(filetransferservice) > 0:
    #Util.remove(filetransferservice);
  #if filesynchronizationservice is not None and len(filesynchronizationservice) > 0:
    #Util.remove(filesynchronizationservice);

  if jsonobject.has('children'):
    children = Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children'));

    for curjsonobject in children[:]:
      currole = curjsonobject.getString("roleName");
      serviceObject = Service.createObjIfRole(objid, curjsonobject, currole, threadPoolLookupPath);
      if serviceObject == 1:
        children.remove(curjsonobject);

    for curjsonobject in children[:]:
      currole = curjsonobject.getString("roleName");
      componentObject = Component.createObjIfRole(objid, curjsonobject, currole, threadPoolLookupPath);
      if (componentObject == 0):
        propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
        if propertyObject == 0:
          if currole == "WebSphereStateManageable":
            StateManageable.create(objid, curjsonobject);        
          elif currole == "WebSphereEndPoint":
            name = curjsonobject.getString('name');
            if name == "NODE_DISCOVERY_ADDRESS":
              oep = Util.getRequiredAttribute(objid, "NODE_DISCOVERY_ADDRESS", "NodeAgent");
              EndPoint.update(oep, curjsonobject);
            else:
              print ("Warning: Attempted to update WebSphereEndPoint but could not find one named NODE_DISCOVERY_ADDRESS." +
              "  Found one with name " + name + ".");
  Util.popPathElement('NodeAgent');

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

  roleProperties = jsonobject.getJSONObject("roleProperties");

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

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

  Component.removeComponents(objid, 'components', "NodeAgent");
  Property.removeProperties(objid, 'properties',"NodeAgent");
  Service.removeServices(objid, 'services', "NodeAgent");

  stateManagement = Util.getRequiredAttribute(objid, 'stateManagement',"NodeAgent");
  if stateManagement is not None and len(stateManagement) > 0:
    Util.remove(stateManagement);      
  
  if jsonobject.has('children'):
    children = Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children'));
    for curjsonobject in children[:]:
      currole = curjsonobject.getString("roleName");
      serviceObject = Service.createObjIfRole(objid, curjsonobject, currole, threadPoolLookupPath);
      if serviceObject == 1:
        children.remove(curjsonobject);

    for curjsonobject in children[:]:
      currole = curjsonobject.getString("roleName");
      componentObject = Component.createObjIfRole(objid, curjsonobject, currole, threadPoolLookupPath);
      if (componentObject == 0):
        propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
        if propertyObject == 0:
          if currole == "WebSphereStateManageable":
            StateManageable.create(objid, curjsonobject);        
          elif currole == "WebSphereEndPoint":
            name = curjsonobject.getString('name');
            if name == "NODE_DISCOVERY_ADDRESS":
              oep = Util.getRequiredAttribute(objid, "NODE_DISCOVERY_ADDRESS", "NodeAgent");
              EndPoint.update(oep, curjsonobject);
            else:
              print ("Warning: Attempted to update WebSphereEndPoint but could not find one named NODE_DISCOVERY_ADDRESS." +
              "  Found one with name " + name + ".");
  Util.popPathElement('NodeAgent');
