from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from Service import Service
from Component import Component
from utilities import Util
from Property import Property
from Classloader import Classloader
from StatisticsProvider import StatisticsProvider
from StateManageable import StateManageable
from LSDConnection import LSDConnection
from WebserverPluginSettings import WebserverPluginSettings

__name_att__ = None;

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


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

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.applicationserver.applicationclassloadingmode", objid, "applicationClassLoadingMode","ApplicationServer");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.applicationserver.name", objid, "name","ApplicationServer");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.applicationserver.id", objid, "id","ApplicationServer");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.applicationserver.jsfprovider", objid, "jsfProvider","ApplicationServer");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.applicationserver.applicationclassloaderpolicy", objid, "applicationClassLoaderPolicy","ApplicationServer");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};

  extraObjects = Component.exportComponents(objid, respath, extraObjects, typeFolders, 'components', "ApplicationServer");

  extraObjects = Service.exportServices(objid, respath, extraObjects, typeFolders, 'services', "ApplicationServer");
  
  i = 0;
  classloaders = Util.parseConfigIdListAttribute(objid, 'classloaders',"ApplicationServer");
  for classloader in classloaders:
    if len(classloader) > 0:
      returndict = Util.createTypeFolder(respath, "Classloader", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      Util.addAllFromExport(extraObjects, Classloader._export(classloader, currespath, "Classloader%s" % i));
      i = i + 1;
  
  statisticsProvider = Util.getOptionalAttribute(objid, 'statisticsProvider',"ApplicationServer");
  if statisticsProvider is not None and len(statisticsProvider) > 0:
    returndict = Util.createTypeFolder(respath, "StatisticsProvider", typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, StatisticsProvider._export(statisticsProvider, currespath, "StatisticsProvider"));
  
  stateManagement = Util.getRequiredAttribute(objid, 'stateManagement',"ApplicationServer");
  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"));  

  lsdConnection = Util.getOptionalAttribute(objid, 'locationServiceDaemon',"ApplicationServer");
  if lsdConnection is not None and len(lsdConnection) > 0:
    returndict = Util.createTypeFolder(respath, "LSDConnection", typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, LSDConnection._export(lsdConnection, currespath, "LSDConnection"));
    
  webserverPluginSettings = Util.getRequiredAttribute(objid, 'webserverPluginSettings',"ApplicationServer");
  if webserverPluginSettings is not None and len(webserverPluginSettings) > 0:
    returndict = Util.createTypeFolder(respath, "WebserverPluginSettings", typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, WebserverPluginSettings._export(webserverPluginSettings, currespath, "WebserverPluginSettings"));    
    
  extraObjects = Property.exportProperties(objid, respath, extraObjects, typeFolders, 'properties',"ApplicationServer");
  
  if len(extraObjects) != 0:
    result['extraObjects'] = extraObjects;
  Util.popPathElement('ApplicationServer');
  return result;



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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  properties = [];
  Util.addIfNotNone(properties, "applicationClassLoadingMode", roleProperties.optString("websphere.applicationserver.applicationclassloadingmode", None));
  Util.addIfNotNone(properties, "name", roleProperties.optString("websphere.applicationserver.name", None));
  Util.addIfNotNone(properties, "id", roleProperties.optString("websphere.applicationserver.id", None));
  Util.addIfNotNone(properties, "jsfProvider", roleProperties.optString("websphere.applicationserver.jsfprovider", None));
  Util.addIfNotNone(properties, "applicationClassLoaderPolicy", roleProperties.optString("websphere.applicationserver.applicationclassloaderpolicy", None));
  print "Creating ApplicationServer with attributes";
  for prop in properties:
    print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };
  objid = Util.create("ApplicationServer", parentid, properties);

  Component.removeComponents(objid, 'components', "ApplicationServer");
  Service.removeServices(objid, 'services', "ApplicationServer");
  Property.removeProperties(objid, 'properties',"ApplicationServer");
  
  classloaders = Util.parseConfigIdListAttribute(objid, 'classloaders',"ApplicationServer");
  for classloader in classloaders:
    if len(classloader) > 0:
      Util.remove(classloader);
  
  statisticsProvider = Util.getOptionalAttribute(objid, 'statisticsProvider',"ApplicationServer");
  if statisticsProvider is not None and len(statisticsProvider) > 0:
    Util.remove(statisticsProvider);
  
  stateManagement = Util.getRequiredAttribute(objid, 'stateManagement',"ApplicationServer");
  if stateManagement is not None and len(stateManagement) > 0:
    Util.remove(stateManagement);
    
  lsdConnection = Util.getOptionalAttribute(objid, 'locationServiceDaemon',"ApplicationServer");
  if lsdConnection is not None and len(lsdConnection) > 0:
    Util.remove(lsdConnection);
    
  webserverPluginSettings = Util.getRequiredAttribute(objid, 'webserverPluginSettings',"ApplicationServer");
  if webserverPluginSettings is not None and len(webserverPluginSettings) > 0:
    Util.remove(webserverPluginSettings);    

  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 == "WebSphereClassloader":
            Classloader.create(objid, curjsonobject);
          elif currole == "WebSphereStatisticsProvider":
            StatisticsProvider.create(objid, curjsonobject);
          elif currole == "WebSphereStateManageable":
            StateManageable.create(objid, curjsonobject);
          elif currole == "WebSphereLSDConnection":
            LSDConnection.create(objid, curjsonobject);
          elif currole == "WebSphereWebserverPluginSettings":
            WebserverPluginSettings.create(objid, curjsonobject);
  Util.popPathElement('ApplicationServer');


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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  atts = [];
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.applicationserver.applicationclassloadingmode", None), "applicationClassLoadingMode","ApplicationServer");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.applicationserver.name", None), "name","ApplicationServer");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.applicationserver.id", None), "id","ApplicationServer");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.applicationserver.jsfprovider", None), "jsfProvider","ApplicationServer");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.applicationserver.applicationclassloaderpolicy", None), "applicationClassLoaderPolicy","ApplicationServer");
  if len(atts) != 0:
    print "Modifying ApplicationServer with attributes:"
    for prop in atts:
      print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };

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

  Component.removeComponents(objid, 'components', "ApplicationServer");
  Service.removeServices(objid, 'services', "ApplicationServer");
  Property.removeProperties(objid, 'properties',"ApplicationServer");
  
  classloaders = Util.parseConfigIdListAttribute(objid, 'classloaders',"ApplicationServer");
  for classloader in classloaders:
    if len(classloader) > 0:
      Util.remove(classloader);
  
  statisticsProvider = Util.getOptionalAttribute(objid, 'statisticsProvider',"ApplicationServer");
  if statisticsProvider is not None and len(statisticsProvider) > 0:
    Util.remove(statisticsProvider);
  
  stateManagement = Util.getRequiredAttribute(objid, 'stateManagement',"ApplicationServer");
  if stateManagement is not None and len(stateManagement) > 0:
    Util.remove(stateManagement);
    
  lsdConnection = Util.getOptionalAttribute(objid, 'locationServiceDaemon',"ApplicationServer");
  if lsdConnection is not None and len(lsdConnection) > 0:
    Util.remove(lsdConnection);
    
  webserverPluginSettings = Util.getRequiredAttribute(objid, 'webserverPluginSettings',"ApplicationServer");
  if webserverPluginSettings is not None and len(webserverPluginSettings) > 0:
    Util.remove(webserverPluginSettings);    

  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 == "WebSphereClassloader":
            Classloader.create(objid, curjsonobject);
          elif currole == "WebSphereStatisticsProvider":
            StatisticsProvider.create(objid, curjsonobject);
          elif currole == "WebSphereStateManageable":
            StateManageable.create(objid, curjsonobject);
          elif currole == "WebSphereLSDConnection":
            LSDConnection.create(objid, curjsonobject);
          elif currole == "WebSphereWebserverPluginSettings":
            WebserverPluginSettings.create(objid, curjsonobject);
  Util.popPathElement('ApplicationServer');
