from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from HTTPConnector import HTTPConnector
from JMSConnector import JMSConnector
from RMIConnector import RMIConnector
from SOAPConnector import SOAPConnector
from IPCConnector import IPCConnector
from JSR160RMIConnector import JSR160RMIConnector
from utilities import Util
from Property import Property
from WASConfLog import Log

__name_att__ = None;

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


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

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.jmxconnector.enable", objid, "enable","JMXConnector");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};
  extraObjects = Property.exportProperties(objid, respath, extraObjects, typeFolders, 'properties',"JMXConnector");
  if len(extraObjects) != 0:
    result['extraObjects'] = extraObjects;
  Util.popPathElement('JMXConnector');
  return result;



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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  properties = [];
  Util.addIfNotNone(properties, "enable", roleProperties.optString("websphere.jmxconnector.enable", None));
  print "Creating JMXConnector with attributes";
  for prop in properties:
    print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };
  objid = Util.create("JMXConnector", parentid, properties);
  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('JMXConnector');

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

  roleProperties = jsonobject.getJSONObject("roleProperties");

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

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

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

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString("roleName");
      propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);
  Util.popPathElement('JMXConnector');

def removeJMXConnectors(objid, attributeName, parentType):
  jmxconnectors = Util.parseConfigIdListAttribute(objid, attributeName, parentType);
  if jmxconnectors is not None and len(jmxconnectors) > 0:
    for jmxconnector in jmxconnectors:
      Util.remove(jmxconnector);

def exportJMXConnectors(objid, respath, extraObjects, typeFolders, attributeName, parentType):
  id2NameDict = {}
  counterHTTPConnector = 0;
  counterJMSConnector = 0;
  counterRMIConnector = 0;
  counterSOAPConnector = 0;
  counterIPCConnector = 0;
  counterJSR160RMIConnector = 0;

  jmxconnectors = Util.parseConfigIdListAttribute(objid, attributeName, parentType);
  if jmxconnectors is not None and len(jmxconnectors) > 0:
    for jmxconnector in jmxconnectors:
      if len(jmxconnector) > 0:
        if jmxconnector.find("#HTTPConnector_") != -1:
          returndict = Util.createTypeFolder(respath, "HTTPConnector", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          name = 'HTTPConnector%s' % counterHTTPConnector;
          Util.addAllFromExport(extraObjects, HTTPConnector._export(jmxconnector, currespath, name));
          id2NameDict[jmxconnector] = name;
          counterHTTPConnector = counterHTTPConnector + 1;
        elif jmxconnector.find("#JMSConnector_") != -1:
          returndict = Util.createTypeFolder(respath, "JMSConnector", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          name = 'JMSConnector%s' % counterJMSConnector;
          Util.addAllFromExport(extraObjects, JMSConnector._export(jmxconnector, currespath, name));
          id2NameDict[jmxconnector] = name;
          counterJMSConnector = counterJMSConnector + 1;
        elif jmxconnector.find("#RMIConnector_") != -1:
          returndict = Util.createTypeFolder(respath, "RMIConnector", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          name = 'RMIConnector%s' % counterRMIConnector;
          Util.addAllFromExport(extraObjects, RMIConnector._export(jmxconnector, currespath, name));
          id2NameDict[jmxconnector] = name;
          counterRMIConnector = counterRMIConnector + 1;
        elif jmxconnector.find("#SOAPConnector_") != -1:
          returndict = Util.createTypeFolder(respath, "SOAPConnector", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          name = 'SOAPConnector%s' % counterSOAPConnector;
          Util.addAllFromExport(extraObjects, SOAPConnector._export(jmxconnector, currespath, name));
          id2NameDict[jmxconnector] = name;
          counterSOAPConnector = counterSOAPConnector + 1;
        elif jmxconnector.find("#IPCConnector_") != -1:
          returndict = Util.createTypeFolder(respath, "IPCConnector", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          name = 'IPCConnector%s' % counterIPCConnector;
          Util.addAllFromExport(extraObjects, IPCConnector._export(jmxconnector, currespath, name));
          id2NameDict[jmxconnector] = name;
          counterIPCConnector = counterIPCConnector + 1;
        elif jmxconnector.find("#JSR160RMIConnector_") != -1:
          returndict = Util.createTypeFolder(respath, "JSR160RMIConnector", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            Util.addFromExport(extraObjects, returndict['object']);
          name = 'JSR160RMIConnector%s' % counterJSR160RMIConnector;
          Util.addAllFromExport(extraObjects, JSR160RMIConnector._export(jmxconnector, currespath, name));
          id2NameDict[jmxconnector] = name;
          counterJSR160RMIConnector = counterJSR160RMIConnector + 1;

  #it makes no sense to return an object that was passed in.
  #instead we will pass a dictionary of configid -> resourceName of discovered connectors for handling references to connectors in AdminService
  return id2NameDict;

def createObjIfRole(objid, curjsonobject, currole, attname = None):
  if attname is None or len(attname) == 0:
    if currole == "WebSphereHTTPConnector":
      return HTTPConnector.create(objid, curjsonobject);
    elif currole == "WebSphereJMSConnector":
      return JMSConnector.create(objid, curjsonobject);
    elif currole == "WebSphereRMIConnector":
      return RMIConnector.create(objid, curjsonobject);
    elif currole == "WebSphereSOAPConnector":
      return SOAPConnector.create(objid, curjsonobject);
    elif currole == "WebSphereIPCConnector":
      return IPCConnector.create(objid, curjsonobject);
    elif currole == "WebSphereJSR160RMIConnector":
      return JSR160RMIConnector.create(objid, curjsonobject);
  else:
    if currole == "WebSphereHTTPConnector":
      return HTTPConnector.create(objid, curjsonobject, attname);
    elif currole == "WebSphereJMSConnector":
      return JMSConnector.create(objid, curjsonobject, attname);
    elif currole == "WebSphereRMIConnector":
      return RMIConnector.create(objid, curjsonobject, attname);
    elif currole == "WebSphereSOAPConnector":
      return SOAPConnector.create(objid, curjsonobject, attname);
    elif currole == "WebSphereIPCConnector":
      return IPCConnector.create(objid, curjsonobject, attname);
    elif currole == "WebSphereJSR160RMIConnector":
      return JSR160RMIConnector.create(objid, curjsonobject, attname);
  #we should return the created objid instead of 0/1 
  #if we didn't handle it we should return none
  return None;

def updateObjIfRole(parentobjid, jsonobject, currole, connname, curConnectorToNameDict):
  if connname in curConnectorToNameDict.keys():
    objid = curConnectorToNameDict[connname];
    if currole == "WebSphereHTTPConnector":
      HTTPConnector.update(objid, jsonobject);
      return objid;
    elif currole == "WebSphereJMSConnector":
      JMSConnector.update(objid, jsonobject);
      return objid;
    elif currole == "WebSphereRMIConnector":
      RMIConnector.update(objid, jsonobject);
      return objid;
    elif currole == "WebSphereSOAPConnector":
      SOAPConnector.update(objid, jsonobject);
      return objid;
    elif currole == "WebSphereIPCConnector":
      IPCConnector.update(objid, jsonobject);
      return objid;
    elif currole == "WebSphereJSR160RMIConnector":
      JSR160RMIConnector.update(objid, jsonobject);
      return objid;
  return None;

def updateJMXConnectors(objid, attName, children, typeName):
  curjmxconnectors = Util.parseConfigIdListAttribute(objid, attName, typeName);
  curConnectorToNameDict = {};
  for conn in curjmxconnectors:
    name = Util.getRequiredAttribute(objid, 'name', Util.getObjectType(objid));
    curConnectorToNameDict[name] = conn;

  connectorName2IdDict = {};
  for curjsonobject in children:
    currole = curjsonobject.getString('roleName');
    curname = curjsonobject.getString('name');
    connectorObject = updateObjIfRole(objid, curjsonobject, currole, curname, curConnectorToNameDict);
    if connectorObject is not None and len(connectorObject) > 0:
      connectorName2IdDict[curname] = connectorObject;
      Log.debug("Adding %(name)s with id %(id)s to dictionary" % { 'name':curname, 'id': connectorObject });
    else:
      connectorObject = createObjIfRole(objid, curjsonobject, currole, attName);
      if connectorObject is not None and len(connectorObject) > 0:
        connectorName2IdDict[curname] = connectorObject;
        Log.debug("Adding %(name)s with id %(id)s to dictionary" % { 'name':curname, 'id': connectorObject });

  for key in connectorName2IdDict.keys():
    if curConnectorToNameDict.has_key(key):
      del curConnectorToNameDict[key];

  for x in curConnectorToNameDict.values():
    Util.remove(x);

  return connectorName2IdDict;
