from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from AppPlacementController import AppPlacementController;
from utilities import Util
from Audit import Audit
from Policy import Policy
from SecurityDomain import SecurityDomain
from Security import Security
from AuthorizationTableExt import AuthorizationTableExt
from HealthController import HealthController
from Property import Property

__name_att__ = "websphere.cell"

def export(objid, parentcontainmentpath, parentrespath):

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

  containmentpath = "%(parentconpath)sCell:%(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('Cell')

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


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

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell", objid, "name","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.enablebidi", objid, "enableBiDi","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.cellregistered", objid, "cellRegistered","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.shortname", objid, "shortName","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.biditextdirection", objid, "biDiTextDirection","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.celldiscoveryprotocol", objid, "cellDiscoveryProtocol","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.celltype", objid, "cellType","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.discoveryaddressendpointname", objid, "discoveryAddressEndpointName","Cell");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.cell.multicastdiscoveryaddressendpointname", objid, "multicastDiscoveryAddressEndpointName","Cell");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};
  extraObjects = Property.exportProperties(objid, respath, extraObjects, typeFolders, 'properties',"Cell");
  apcConPath = "/Cell:/AppPlacementController:/";# i know there can only be zero or one
  apc = Util.getid(apcConPath, ['AppPlacementController']);
  if apc is not None and len(apc.splitlines()) > 1:
    raise Exception("More than 1 APC found at Cell level!");

  if apc is not None and len(apc) > 0:
    returndict = Util.createTypeFolder(respath, "Application Placement Controller", typeFolders, 1);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, AppPlacementController._export(apc, currespath, "Application Placement Controller"));

  i = 0;
  auditConPath = "/Cell:%(name)s/Audit:/" % { 'name':name }
  audits = Util.getid(auditConPath, ['Audit']);
  if audits is not None and len(audits) > 0:
    auditList = audits.splitlines();
    for audit in auditList:
      if len(audit) > 0:
        returndict = Util.createTypeFolder(respath, "Audit", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          Util.addFromExport(extraObjects, returndict['object']);
        Util.addAllFromExport(extraObjects, Audit._export(audit, currespath, "Audit%s" % i));
        i = i + 1;

  i = 0;
  policies = Util.getid("/Policy:/", ['Policy']);
  if policies is not None and len(policies) > 0:
    policyList = policies.splitlines();
    for policy in policyList:
      if len(policy) > 0:
        returndict = Util.createTypeFolder(respath, "Policy", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          Util.addFromExport(extraObjects, returndict['object']);
        Util.addAllFromExport(extraObjects, Policy._export(policy, currespath, "Policy%s" % i));
        i = i + 1;

  securityDomains = SecurityDomain.getSecurityDomains(objid);
  if securityDomains is not None and len(securityDomains) > 0:
    securityDomainList = securityDomains;
    for securityDomain in securityDomainList:
      if len(securityDomain) > 0:
        returndict = Util.createTypeFolder(respath, "SecurityDomain", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          Util.addFromExport(extraObjects, returndict['object']);
        Util.addAllFromExport(extraObjects, SecurityDomain._export(securityDomain, currespath));

  i = 0;
  authorizationTableExts = AuthorizationTableExt.getAuthorizationTableExts(objid);
  if authorizationTableExts is not None and len(authorizationTableExts) > 0:
    authorizationTableExtList = authorizationTableExts;
    for authorizationTableExt in authorizationTableExtList:
      if len(authorizationTableExt) > 0 and authorizationTableExt.find("/authorizationgroups/") == -1:
        returndict = Util.createTypeFolder(respath, "AuthorizationTableExt", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          Util.addFromExport(extraObjects, returndict['object']);
        Util.addAllFromExport(extraObjects, AuthorizationTableExt._export(authorizationTableExt, currespath, "AuthorizationTableExt%s" % i));
        i = i + 1;

  secfolderretdict = Util.createTypeFolder(respath, "Security", typeFolders);
  secresfolpath = secfolderretdict['path'];
  if secfolderretdict.has_key('object'):
    Util.addFromExport(extraObjects, secfolderretdict['object']);
  Util.addAllFromExport(extraObjects, Security._export(objid, secresfolpath, "Security"));

  healthController = Util.getid("/HealthController:/", ['HealthController']);
  if healthController is not None and len(healthController) > 0:
    returndict = Util.createTypeFolder(respath, "HealthController_Cell", typeFolders);
    currespath = returndict['path'];
    if returndict.has_key('object'):
      Util.addFromExport(extraObjects, returndict['object']);
    Util.addAllFromExport(extraObjects, HealthController._export(healthController, currespath, "Health Controller"));

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



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

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

  objid = Util.getid(containmentpath);
  if objid == None or len(objid) == 0:
    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 Cell on.");
    objid = create(parentid, jsonobject);
  else:
    update(objid,jsonobject);
  return objid;

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

#i would be amazed if this is even a supported operation
def create(parentid, jsonobject):
  Util.pushPathElement('Cell')
  if not jsonobject.has("roleProperties"):
    raise Exception("Cell resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");

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

  properties = [];
  Util.addIfNotNone(properties, "name", roleProperties.optString("websphere.cell", None));
  Util.addIfNotNone(properties, "enableBiDi", roleProperties.optString("websphere.cell.enablebidi", "false"));
  Util.addIfNotNone(properties, "cellRegistered", roleProperties.optString("websphere.cell.cellregistered", None));
  Util.addIfNotNone(properties, "shortName", roleProperties.optString("websphere.cell.shortname", None));
  Util.addIfNotNone(properties, "biDiTextDirection", roleProperties.optString("websphere.cell.biditextdirection", "LTR"));
  Util.addIfNotNone(properties, "cellDiscoveryProtocol", roleProperties.optString("websphere.cell.celldiscoveryprotocol", None));
  Util.addIfNotNone(properties, "cellType", roleProperties.optString("websphere.cell.celltype", None));
  Util.addIfNotNone(properties, "discoveryAddressEndpointName", roleProperties.optString("websphere.cell.discoveryaddressendpointname", None));
  Util.addIfNotNone(properties, "multicastDiscoveryAddressEndpointName", roleProperties.optString("websphere.cell.multicastdiscoveryaddressendpointname", None));
  print "Creating Cell with attributes";
  for prop in properties:
    print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };

  objid = Util.create("Cell", parentid, properties);
  apcConPath = "/Cell:/AppPlacementController:/";#there can be only one
  apc = Util.getid(apcConPath, ['AppPlacementController']);
  if apc is not None and len(apc.splitlines()) > 1:
    raise Exception("More than 1 APC found at Cell level!");

  name = roleProperties.optString("websphere.cell", None);
  auditConPath = "/Cell:%(name)s/Audit:/" % { 'name':name }
  audits = Util.getid(auditConPath, ['Audit']);
  if audits is not None and len(audits) > 0:
    auditList = audits.splitlines();
    for audit in auditList:
      if len(audit) > 0:
        Util.remove(audit);

  securityDomains = SecurityDomain.getSecurityDomains(objid);
  if securityDomains is not None and len(securityDomains) > 0:
    securityDomainList = securityDomains;
    for securityDomain in securityDomainList:
      if len(securityDomain) > 0:
        Util.remove(securityDomain);

  authorizationTableExts = AuthorizationTableExt.getAuthorizationTableExts(objid);
  if authorizationTableExts is not None and len(authorizationTableExts) > 0:
    authorizationTableExtList = authorizationTableExts;
    for authorizationTableExt in authorizationTableExtList:
      if len(authorizationTableExt) > 0 and authorizationTableExt.find("/authorizationgroups/") == -1:
        Util.remove(authorizationTableExt);

  healthController = Util.getid("/HealthController:/", ['HealthController']);

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      if currole == "WebSphereAppPlacementController":
        if apc is not None and len(apc) > 0:
          AppPlacementController.update(apc, curjsonobject, None);
        else:
          AppPlacementController.create(objid, curjsonobject, None);
      elif currole == "WebSphereAudit":
        Audit.create(objid, curjsonobject);
      elif currole == "WebSphereSecurityDomain":
        SecurityDomain.create(objid, curjsonobject);
      elif currole == "WebSpherePolicy":
        policy = Util.getid("/Policy:/", ['Policy']);
        if policy is not None and len(policy) > 0:
          Policy.update(policy, curjsonobject);
      #else: Do not know how to create Policy object since it is the root object
      elif currole == "WebSphereAuthorizationTableExt":
        AuthorizationTableExt.create(objid, curjsonobject);
      elif currole == "WebSphereSecurity":
        Security.update(objid, curjsonobject);
      elif currole == "WebSphereHealthController":
        HealthController.update(healthController, curjsonobject, None);
      else:
        propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('Cell');


  return objid;

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

  roleProperties = jsonobject.getJSONObject("roleProperties");

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

  atts = [];
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell", None), "name","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.enablebidi", "false"), "enableBiDi","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.cellregistered", None), "cellRegistered","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.shortname", None), "shortName","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.biditextdirection", "LTR"), "biDiTextDirection","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.celldiscoveryprotocol", None), "cellDiscoveryProtocol","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.celltype", None), "cellType","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.discoveryaddressendpointname", None), "discoveryAddressEndpointName","Cell");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.cell.multicastdiscoveryaddressendpointname", None), "multicastDiscoveryAddressEndpointName","Cell");
  if len(atts) != 0:
    print "Modifying Cell with attributes:"
    for prop in atts:
      print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };

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

  apcConPath = "/Cell:/AppPlacementController:/";#there can be only one
  apc = Util.getid(apcConPath, ['AppPlacementController']);
  if apc is not None and len(apc.splitlines()) > 1:
    raise Exception("More than 1 APC found at Cell level!");

  name = roleProperties.optString("websphere.cell", None);
  auditConPath = "/Cell:%(name)s/Audit:/" % { 'name':name }
  audits = Util.getid(auditConPath, ['Audit']);
  if audits is not None and len(audits) > 0:
    auditList = audits.splitlines();
    for audit in auditList:
      if len(audit) > 0:
        Util.remove(audit);

  securityDomains = SecurityDomain.getSecurityDomains(objid);
  for securityDomain1 in securityDomains:
    if len(securityDomain1) > 0:
      Util.remove(securityDomain1);

  authorizationTableExts = AuthorizationTableExt.getAuthorizationTableExts(objid);
  if authorizationTableExts is not None and len(authorizationTableExts) > 0:
    authorizationTableExtList = authorizationTableExts;
    for authorizationTableExt in authorizationTableExtList:
      if len(authorizationTableExt) > 0 and authorizationTableExt.find("/authorizationgroups/") == -1:
        Util.remove(authorizationTableExt);

  Property.removeProperties(objid, 'properties',"Cell");

  healthController = Util.getid("/HealthController:/", ['HealthController']);

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      if currole == "WebSphereAppPlacementController":
        if apc is not None and len(apc) > 0:
          AppPlacementController.update(apc, curjsonobject, None);
        else:
          AppPlacementController.create(objid, curjsonobject, None);
      elif currole == "WebSphereAudit":
        Audit.create(objid, curjsonobject);
      elif currole == "WebSphereSecurityDomain":
        SecurityDomain.create(objid, curjsonobject);
      elif currole == "WebSpherePolicy":
        policy = Util.getid("/Policy:/", ['Policy']);
        if policy is not None and len(policy) > 0:
          Policy.update(policy, curjsonobject);
      elif currole == "WebSphereAuthorizationTableExt":
        AuthorizationTableExt.create(objid, curjsonobject);
      elif currole == "WebSphereSecurity":
        Security.update(objid, curjsonobject);
      elif currole == "WebSphereHealthController":
        HealthController.update(healthController, curjsonobject, None);
      else:
        propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('Cell');
