from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from utilities import Util
from SIBDatastore import SIBDatastore
from SIBFilestore import SIBFilestore
from ThreadPool import ThreadPool
from SIBMediationExecutionPoint import SIBMediationExecutionPoint
from SIBGatewayLink import SIBGatewayLink
from SIBMQClientLink import SIBMQClientLink
from SIBMQLink import SIBMQLink
from SIBLocalizationPoint import SIBLocalizationPoint
from WASConfLog import Log
from Property import Property

__name_att__ = "websphere.sibmessagingengine.name";

def export(objid, parentcontainmentpath, parentrespath):

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

  containmentpath = "%(parentconpath)sSIBMessagingEngine:%(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, name = ""):
  Util.pushPathElement('SIBMessagingEngine')

  if name is None or len(name) <1:
    name = Util.getRequiredAttribute(objid, "name", 'SIBMessagingEngine');

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

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.recovermessagestore", objid, "recoverMessageStore","SIBMessagingEngine");
  Util.addAttributePathPropertyToJson(roleProperties, "websphere.sibmessagingengine.customgroup", objid, "customGroup","SIBMessagingEngine");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.messagestorerecovered", objid, "messageStoreRecovered","SIBMessagingEngine");
#  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.busuuid", objid, "busUuid","SIBMessagingEngine");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.messagestoretype", objid, "messageStoreType","SIBMessagingEngine");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.busname", objid, "busName","SIBMessagingEngine");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.description", objid, "description","SIBMessagingEngine");
#  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.uuid", objid, "uuid","SIBMessagingEngine");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.initialstate", objid, "initialState","SIBMessagingEngine");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.highmessagethreshold", objid, "highMessageThreshold","SIBMessagingEngine");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.sibmessagingengine.name", objid, "name","SIBMessagingEngine");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};
  extraObjects = Property.exportProperties(objid, respath, extraObjects, typeFolders, 'properties',"SIBMessagingEngine");
  extraObjects = SIBLocalizationPoint.exportLocalizationPoints(objid, respath, extraObjects, typeFolders, 'localizationPoints',"SIBMessagingEngine");

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

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

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

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

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

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

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

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

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

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

  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 SIBMessagingEngine on.");
    objid = create(parentid, jsonobject, containmentpath);
  else:
    update(objid, jsonobject, containmentpath);

  return objid;

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

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

  properties = [];
  Util.addIfNotNone(properties, "recoverMessageStore", roleProperties.optString("websphere.sibmessagingengine.recovermessagestore", "false"));
  Util.addPathProperty(properties, "customGroup", roleProperties.optString("websphere.sibmessagingengine.customgroup", None));
  Util.addIfNotNone(properties, "messageStoreRecovered", roleProperties.optString("websphere.sibmessagingengine.messagestorerecovered", "false"));
  Util.addIfNotNone(properties, "busUuid", roleProperties.optString("websphere.sibmessagingengine.busuuid", None));
  Util.addIfNotNone(properties, "messageStoreType", roleProperties.optString("websphere.sibmessagingengine.messagestoretype", None));
  Util.addIfNotNone(properties, "busName", roleProperties.optString("websphere.sibmessagingengine.busname", None));
  Util.addIfNotNone(properties, "description", roleProperties.optString("websphere.sibmessagingengine.description", None));
  Util.addIfNotNone(properties, "uuid", roleProperties.optString("websphere.sibmessagingengine.uuid", None));
  Util.addIfNotNone(properties, "initialState", roleProperties.optString("websphere.sibmessagingengine.initialstate", None));
  Util.addIfNotNone(properties, "highMessageThreshold", roleProperties.optString("websphere.sibmessagingengine.highmessagethreshold", None));
  Util.addIfNotNone(properties, "name", roleProperties.optString("websphere.sibmessagingengine.name", None));

  # need to find the busUuid if it is not in the config data
  configDataBusUuid = roleProperties.optString("websphere.sibmessagingengine.busuuid", None);
  if configDataBusUuid == "" or configDataBusUuid is None:
    busName = roleProperties.optString("websphere.sibmessagingengine.busname", None);
    busUuid = getSIBusUUID(busName);
    Util.addIfNotNone(properties, "busUuid", busUuid);

  print "Creating SIBMessagingEngine with attributes";
  for prop in properties:
    print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };
  objid = Util.create("SIBMessagingEngine", parentid, properties);

  # need to create SIBMemberTarget if it doesn't exist
  # first, see if the SIBusMemberTarget exists
  engineUuid = Util.getOptionalAttribute(objid, 'uuid', "SIBMessagingEngine");
  siBusMemberTargetExists = doesSIBusMemberTargetExist(objid, busName, engineUuid);
  if siBusMemberTargetExists == "false":
    # no SIBusMemberTarget exsists, so we will create it.
    # first, need to find the parent SIBusMember
    # to do so, need to examine the containment path for this SIBMessageEngine
    # SIBMessageEngines can exist on servers or clusters
    # Need to figure out which one we are dealing with
    parentSIBusMember = ""
    node = "";
    server = "";
    cluster = "";

    if parentid.find("/clusters/") == -1:
      # this must be a server
      if parentid.find("/servers/") == -1:
        raise Exception("Could not find cluster or server for " + str(parentid));
      nodeStart = parentid.find("/nodes/") + 7;
      nodeEnd = parentid.find("/servers/");
      node = parentid[nodeStart:nodeEnd];
      serverStart = parentid.find("/servers/") + 9;
      serverEnd = parentid.find("|");
      server = parentid[serverStart:serverEnd];
    else:
      clusterStart = parentid.find("/clusters/") + 10;
      clusterEnd = parentid.find("|");
      cluster = parentid[clusterStart:clusterEnd];

    print str(objid) + " has:"
    print "     node = " + str(node);
    print "     server = " + str(server);
    print "     cluster = " + str(cluster);

    # get all SIBusMembers
    siBusMembers = Util.getid("/SIBus:%s/SIBusMember:/" % busName);
    if server != "":
      for siBusMember in siBusMembers.splitlines():
        if len(siBusMember) > 0:
          foundServer = Util.getOptionalAttribute(siBusMember, 'server',"SIBusMember");
          foundNode = Util.getOptionalAttribute(siBusMember, 'node',"SIBusMember");
          if foundServer == server and foundNode == node:
            parentSIBusMember = siBusMember;
            break;
    if cluster != "":
      for siBusMember in siBusMembers.splitlines():
        if len(siBusMember) > 0:
          foundCluster = Util.getOptionalAttribute(siBusMember, 'cluster',"SIBusMember");
          if foundCluster == cluster:
            parentSIBusMember = siBusMember;
            break;

    if parentSIBusMember == "":
      raise Exception("Unable to find the parent SIBusMember when trying to create SIBusMemberTargets.");

    propsMap = [];
    engineName = roleProperties.optString("websphere.sibmessagingengine.name", None)
    engineNameProp = ['engineName', engineName];
    propsMap.append(engineNameProp);

    engineUuidProp = ['engineUuid', engineUuid];
    propsMap.append(engineUuidProp);
    siBusObjid = getSIBus(busName);
    Util.create("SIBusMemberTarget", parentSIBusMember, propsMap, None, 1);
    print "Finished creating SIBusMemberTarget for SIBMessagingEngine " + str(objid)

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString('roleName');
      localizationPointObject = 0;
      localizationPointObject = SIBLocalizationPoint.createObjIfRole(objid, curjsonobject, currole, busName);
      if (localizationPointObject == 0):
        if currole == "WebSphereSIBDatastore":
          SIBDatastore.create(objid, curjsonobject);
        elif currole == "WebSphereSIBFilestore":
          SIBFilestore.create(objid, curjsonobject);
        elif currole == "WebSphereThreadPool":
          ThreadPool.create(objid, curjsonobject);
        elif currole == "WebSphereSIBMediationExecutionPoint":
          SIBMediationExecutionPoint.create(objid, curjsonobject);
        elif currole == "WebSphereSIBGatewayLink":
          SIBGatewayLink.create(objid, curjsonobject);
        elif currole == "WebSphereSIBMQClientLink":
          SIBMQClientLink.create(objid, curjsonobject);
        elif currole == "WebSphereSIBMQLink":
          SIBMQLink.create(objid, curjsonobject, containmentpath);
        else:
          propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('SIBMessagingEngine');

  return objid;

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

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

  atts = [];
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.recovermessagestore", "false"), "recoverMessageStore","SIBMessagingEngine");
  Util.addPathAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.customgroup", None), "customGroup","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.messagestorerecovered", "false"), "messageStoreRecovered","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.busuuid", None), "busUuid","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.messagestoretype", None), "messageStoreType","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.busname", None), "busName","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.description", None), "description","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.uuid", None), "uuid","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.initialstate", None), "initialState","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.highmessagethreshold", None), "highMessageThreshold","SIBMessagingEngine");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.sibmessagingengine.name", None), "name","SIBMessagingEngine");
  if len(atts) != 0:
    print "Modifying SIBMessagingEngine with attributes:"
    for prop in atts:
      print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };

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

  SIBLocalizationPoint.removeLocalizationPoints(objid, 'localizationPoints',"SIBMessagingEngine");

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

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

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

  executionPoints = Util.parseConfigIdListAttribute(objid, 'executionPoints', "SIBMessagingEngine");
  for executionPoint in executionPoints:
    Util.remove(executionPoint);

  gatewayLinks = Util.parseConfigIdListAttribute(objid, 'gatewayLink', "SIBMessagingEngine");
  for gatewayLink in gatewayLinks:
    Util.remove(gatewayLink);

  mqClientLinks = Util.parseConfigIdListAttribute(objid, 'mqClientLink', "SIBMessagingEngine");
  for mqClientLink in mqClientLinks:
    Util.remove(mqClientLink);

  mqLinks = Util.parseConfigIdListAttribute(objid, 'mqLink', "SIBMessagingEngine");
  for mqLink in mqLinks:
    Util.remove(mqLink);

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

  busName = roleProperties.optString("websphere.sibmessagingengine.busname", None)

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString('roleName');
      localizationPointObject = 0;
      localizationPointObject = SIBLocalizationPoint.createObjIfRole(objid, curjsonobject, currole, busName);
      if (localizationPointObject == 0):
        if currole == "WebSphereSIBDatastore":
          SIBDatastore.create(objid, curjsonobject);
        elif currole == "WebSphereSIBFilestore":
          SIBFilestore.create(objid, curjsonobject);
        elif currole == "WebSphereThreadPool":
          ThreadPool.create(objid, curjsonobject);
        elif currole == "WebSphereSIBMediationExecutionPoint":
          SIBMediationExecutionPoint.create(objid, curjsonobject);
        elif currole == "WebSphereSIBGatewayLink":
          SIBGatewayLink.create(objid, curjsonobject);
        elif currole == "WebSphereSIBMQClientLink":
          SIBMQClientLink.create(objid, curjsonobject);
        elif currole == "WebSphereSIBMQLink":
          SIBMQLink.create(objid, curjsonobject, containmentpath);
        else:
          propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('SIBMessagingEngine');

def getSIBus(siBusName):
  siBusObjid = Util.getid("/SIBus:%s/" % siBusName);
  return siBusObjid;

def getSIBusUUID(siBusName):
  siBusObjid = getSIBus(siBusName);
  if siBusObjid is None or siBusObjid == "":
    raise Exception("While attempting to create a SIBMessagingEngine, could not find SIBus named " + str(siBusName));
  siBusUuid = Util.getOptionalAttribute(siBusObjid, 'uuid',"SIBus");
  return siBusUuid;

def doesSIBusMemberTargetExist(objid, busName, engineUuid):
  siBusMemberTargetExists = "false";
  print "engineUuid is " + str(engineUuid) + " for " + str(objid);
  # get all SIBusMemberTargets
  siBusMemberTargets = Util.getid("/SIBus:%s/SIBusMember:/SIBusMemberTarget:/" % busName);
  for siBusMemberTarget in siBusMemberTargets.splitlines():
    if len(siBusMemberTarget) > 0:
      targetEngineUuid = Util.getOptionalAttribute(siBusMemberTarget, 'engineUuid', "SIBusMemberTarget");
      if targetEngineUuid == engineUuid:
        print "SIBusMemberTarget already exists for " + str(objid) + " and it is " + str(siBusMemberTarget);
        siBusMemberTargetExists = "true";
        break;
  return siBusMemberTargetExists;
