from org.codehaus.jettison.json import JSONObject, JSONArray
from NamedEndPoint import NamedEndPoint
from ExtendedApplicationData import ExtendedApplicationData
from RecoveryLog import RecoveryLog
from utilities import Util
from WASConfLog import Log;

__name_att__ = None;

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


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

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.serverentry.servername", objid, "serverName","ServerEntry");
  Util.addAttributePathPropertyToJson(roleProperties, "websphere.serverentry.deployedapplications", objid, "deployedApplications","ServerEntry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.serverentry.serverdisplayname", objid, "serverDisplayName","ServerEntry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.serverentry.servertype", objid, "serverType","ServerEntry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.serverentry.serveruniqueid", objid, "serverUniqueId","ServerEntry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.serverentry.genericshortname", objid, "genericShortName","ServerEntry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.serverentry.servershortname", objid, "serverShortName","ServerEntry");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};

  i = 0;
  endPoints = Util.parseConfigIdListAttribute(objid, 'specialEndpoints', "ServerEntry");
  scope = Util.getSecurityScopename(objid);
  for endPoint in endPoints:
    if len(endPoint) > 0:
      returndict = Util.createTypeFolder(respath, "NamedEndPoint", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        Util.addFromExport(extraObjects, returndict['object']);
      endPointName = Util.getOptionalAttribute(endPoint, "endPointName", "NamedEndPoint");
      if len(endPointName) > 0:
        Util.addAllFromExport(extraObjects, NamedEndPoint._export(endPoint, currespath, scope, endPointName));
      else:
        Util.addAllFromExport(extraObjects, NamedEndPoint._export(endPoint, currespath, scope, "NamedEndPoint%s" % i));
      i = i + 1;

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

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

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



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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  properties = [];
  Util.addIfNotNone(properties, "serverName", roleProperties.optString("websphere.serverentry.servername", None));
  Util.addPathProperty(properties, "deployedApplications", roleProperties.optString("websphere.serverentry.deployedapplications", None));
  Util.addIfNotNone(properties, "serverDisplayName", roleProperties.optString("websphere.serverentry.serverdisplayname", None));
  #Util.addIfNotNone(properties, "serverType", roleProperties.optString("websphere.serverentry.servertype", None));
  Util.addIfNotNone(properties, "serverUniqueId", roleProperties.optString("websphere.serverentry.serveruniqueid", None));
  Util.addIfNotNone(properties, "genericShortName", roleProperties.optString("websphere.serverentry.genericshortname", None));
  Util.addIfNotNone(properties, "serverShortName", roleProperties.optString("websphere.serverentry.servershortname", None));
  Log.log("Creating ServerEntry with attributes");
  for prop in properties:
    Log.log("%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] });
  objid = Util.create("ServerEntry", parentid, properties);

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      if currole == "WebSphereNamedEndPoint":
        NamedEndPoint.create(objid, curjsonobject);
      elif currole == "WebSphereExtendedApplicationData":
        ExtendedApplicationData.create(objid, curjsonobject);
      elif currole == "WebSphereRecoveryLog":
        RecoveryLog.create(objid, curjsonobject);
  Util.popPathElement('ServerEntry');

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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  atts = [];
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.serverentry.servername", None), "serverName","ServerEntry");
  # Do not update deployedapplications attribute.  If you do, then it will break the case where the user captured the configuration
  # and then deployed a new application to the server.  When the new application is installed, the only server config data that is updated is this one attribute and if
  # we replace it the the original value, then the newly installed application will fail to start.  We recognize the fact that
  # live compare will now show this 1 difference after the apply is performed; however, it is felt that difference is accurate
  # since a new application was installed to the server after the original configuration was captured.
  #Util.addPathAttIfChanged(objid, atts, roleProperties.optString("websphere.serverentry.deployedapplications", None), "deployedApplications","ServerEntry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.serverentry.serverdisplayname", None), "serverDisplayName","ServerEntry");
  #Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.serverentry.servertype", None), "serverType","ServerEntry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.serverentry.serveruniqueid", None), "serverUniqueId","ServerEntry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.serverentry.genericshortname", None), "genericShortName","ServerEntry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.serverentry.servershortname", None), "serverShortName","ServerEntry");
  if len(atts) != 0:
    Log.log("Modifying ServerEntry with attributes:")
    for prop in atts:
      Log.log("%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] });

    Util.modify(objid, atts);
  else:   
    Log.log("ServerEntry configuration up to date.");

  scope = Util.getSecurityScopename(objid);
  endPoints = Util.parseConfigIdListAttribute(objid, 'specialEndpoints', "ServerEntry");
  for endPoint in endPoints:
    endPointName = Util.getOptionalAttribute(endPoint, "endPointName", "NamedEndPoint")
    if endPointName != None:
      # SSLConfigGroups for NamedEndPoints need to be deleted separately from NamedEndPoints
      endPointScope = scope + ":(endpoint):%s" % endPointName
      NamedEndPoint.deleteNamedEndPointSSLConfigGroups(endPointName, endPointScope)
    Util.remove(endPoint);

  extendedElements = Util.parseConfigIdListAttribute(objid, 'extendedApplicationDataElements', "ServerEntry");
  for extendedElement in extendedElements:
    Util.remove(extendedElement);

  recoveryLog = Util.getOptionalAttribute(objid, 'recoveryLog', "ServerEntry");
  if (recoveryLog is not None) and (len(recoveryLog) > 0):
    Util.remove(recoveryLog);

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      if currole == "WebSphereNamedEndPoint":
        NamedEndPoint.create(objid, curjsonobject);
      elif currole == "WebSphereExtendedApplicationData":
        ExtendedApplicationData.create(objid, curjsonobject);
      elif currole == "WebSphereRecoveryLog":
        RecoveryLog.create(objid, curjsonobject);
  Util.popPathElement('ServerEntry');
