from org.codehaus.jettison.json import JSONObject, JSONArray
from utilities import Util
from Property import Property
from LDAPRepository import LDAPRepository
from CustomRepository import CustomRepository
from FileRepository import FileRepository
from FederatedRepositoryAttributeMapping import FederatedRepositoryAttributeMapping
from SupportedEntityType import SupportedEntityType

__name_att__ = None;

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


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

  roleProperties = JSONObject();

  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.useregistryrealm", objid, "useRegistryRealm","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.serverpassword", objid, "serverPassword","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.primaryadminid", objid, "primaryAdminId","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.useregistryserverid", objid, "useRegistryServerId","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.limit", objid, "limit","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.serverid", objid, "serverId","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.realm", objid, "realm","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.ignorecase", objid, "ignoreCase","WIMUserRegistry");
  Util.addAttributeToJsonIfNotNone(roleProperties, "websphere.wimuserregistry.registryclassname", objid, "registryClassName","WIMUserRegistry");
  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};
  extraObjects = Property.exportProperties(objid, respath, extraObjects, typeFolders, 'properties',"WIMUserRegistry");

  # Get list of repositories in realm
  repolist = Util.listIdMgrRepositories();
  # Remove brackets, if needed
  if repolist.startswith("{"):
    repolist = repolist[1:-1];
  if repolist is not None and len(repolist) > 0:
    repos = repolist.split("}, ");
    for repo in repos:
      if len(repo) > 0:
        name = repo[0:repo.find("=")];
        if repo.find("repositoryType=LDAP") != -1:
          returndict = Util.createTypeFolder(respath, "LDAPRepository", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            extraObjects.append(returndict['object']);
          Util.addAllFromExport(extraObjects, LDAPRepository._export(currespath, name));
        elif repo.find("repositoryType=Custom") != -1:
          returndict = Util.createTypeFolder(respath, "CustomRepository", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            extraObjects.append(returndict['object']);
          Util.addAllFromExport(extraObjects, CustomRepository._export(currespath, name));
        elif repo.find("repositoryType=File") != -1:
          returndict = Util.createTypeFolder(respath, "FileRepository", typeFolders);
          currespath = returndict['path'];
          if returndict.has_key('object'):
            extraObjects.append(returndict['object']);
          Util.addAllFromExport(extraObjects, FileRepository._export(currespath, name));

  # Get the Attribute Mappings
  attMappings = Util.getRealmURAttrMappings();
  if len(attMappings) > 0:
    for attMapping in attMappings:
      attribute = attMapping[0];
      propertyForOutput = attMapping[1];
      propertyForInput = attMapping[2];
      returndict = Util.createTypeFolder(respath, "FederatedRepositoryAttributeMapping", typeFolders);
      currespath = returndict['path'];
      if returndict.has_key('object'):
        extraObjects.append(returndict['object']);
      Util.addAllFromExport(extraObjects, FederatedRepositoryAttributeMapping._export(currespath, attribute, propertyForOutput, propertyForInput));

  # Get the Supported Entity Types
  types = Util.listIdMgrSupportedEntityTypes();
  if types != None:
    for type in types.splitlines():
      if len(type) > 0:
        getIdMgrSupportedEntityTypeParams = "[-name " + type + "]";
        typeDetails = Util.getIdMgrSupportedEntityType(getIdMgrSupportedEntityTypeParams);
        # typeDetails can be in the format
        #    {name=OrgContainer, defaultParent=o=defaultWIMFileBasedRealm, rdnProperties=[o, ou, dc, cn]}
        # or
        #    {rdnProperties=[o, ou, dc, cn], defaultParent=o=defaultWIMFileBasedRealm, name=OrgContainer}
        rdnProperties = typeDetails[typeDetails.find("rdnProperties=[")+15:typeDetails.find("]",typeDetails.find("rdnProperties=[")+15)];        
        # value of defaultParent ends with either , or }
        comma = typeDetails.find(",", typeDetails.find("defaultParent=")+14);
        bracket = typeDetails.find("}", typeDetails.find("defaultParent=")+14);
        endIndex = None;
        if comma != -1 and comma < bracket:
          endIndex = comma;
        else:
          endIndex = bracket;
        defaultParent = typeDetails[typeDetails.find("defaultParent=")+14:endIndex];

        # value of name ends with either , or }
        comma = typeDetails.find(",", typeDetails.find("name=")+5);
        bracket = typeDetails.find("}", typeDetails.find("name=")+5);
        endIndex = None;
        if comma != -1 and comma < bracket:
          endIndex = comma;
        else:
          endIndex = bracket;
        name = typeDetails[typeDetails.find("name=")+5:endIndex];

        returndict = Util.createTypeFolder(respath, "SupportedEntityType", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          extraObjects.append(returndict['object']);
        Util.addAllFromExport(extraObjects, SupportedEntityType._export(currespath, name, defaultParent, rdnProperties));

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

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

  roleProperties = jsonobject.getJSONObject("roleProperties");
  properties = [];
  Util.addIfNotNone(properties, "useRegistryRealm", roleProperties.optString("websphere.wimuserregistry.useregistryrealm", None));
  Util.addIfNotNone(properties, "serverPassword", roleProperties.optString("websphere.wimuserregistry.serverpassword", None));
  Util.addIfNotNone(properties, "primaryAdminId", roleProperties.optString("websphere.wimuserregistry.primaryadminid", None));
  Util.addIfNotNone(properties, "useRegistryServerId", roleProperties.optString("websphere.wimuserregistry.useregistryserverid", None));
  Util.addIfNotNone(properties, "limit", roleProperties.optString("websphere.wimuserregistry.limit", None));
  Util.addIfNotNone(properties, "serverId", roleProperties.optString("websphere.wimuserregistry.serverid", None));
  Util.addIfNotNone(properties, "realm", roleProperties.optString("websphere.wimuserregistry.realm", None));
  Util.addIfNotNone(properties, "ignoreCase", roleProperties.optString("websphere.wimuserregistry.ignorecase", None));
  Util.addIfNotNone(properties, "registryClassName", roleProperties.optString("websphere.wimuserregistry.registryclassname", None));
  print "Creating WIMUserRegistry with attributes";
  for prop in properties:
    print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };
  objid = Util.create("WIMUserRegistry", 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('WIMUserRegistry');

def update(parentid,jsonobject):
  Util.pushPathElement('WIMUserRegistry')
  objid = getWIMUserRegistry(parentid)[0];

  if not jsonobject.has("roleProperties"):
    raise Exception("WIMUserRegistry resource has no role properties!");

  roleProperties = jsonobject.getJSONObject("roleProperties");

  atts = [];
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.useregistryrealm", None), "useRegistryRealm","WIMUserRegistry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.serverpassword", None), "serverPassword","WIMUserRegistry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.primaryadminid", None), "primaryAdminId","WIMUserRegistry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.useregistryserverid", None), "useRegistryServerId","WIMUserRegistry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.limit", None), "limit","WIMUserRegistry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.serverid", None), "serverId","WIMUserRegistry");
  realm = roleProperties.optString("websphere.wimuserregistry.realm", None)
  Util.addAttIfChanged(objid, atts, realm, "realm","WIMUserRegistry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.ignorecase", None), "ignoreCase","WIMUserRegistry");
  Util.addAttIfChanged(objid, atts, roleProperties.optString("websphere.wimuserregistry.registryclassname", None), "registryClassName","WIMUserRegistry");
  if len(atts) != 0:
    print "Modifying WIMUserRegistry with attributes:"
    for prop in atts:
      print "%(name)s = %(value)s" % { 'name': prop[0], 'value': prop[1] };

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

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

  # Get list of existing repositories in realm
  # We will use this later to determine if any repositories need to be deleted
  repos = None;
  repolist = Util.listIdMgrRepositories();
  if repolist is not None and len(repolist) > 0:
    # Remove brackets, if needed
    if repolist.startswith("{"):
      repolist = repolist[1:-1];
    repos = repolist.split("}, ");

  handledRepos = [];
  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString('roleName');
      if currole == "WebSphereLDAPRepository":
        LDAPRepository.update(objid, curjsonobject, realm);
        roleProperties = curjsonobject.getJSONObject("roleProperties");
        id = roleProperties.optString("id", None);
        handledRepos.append(id);
      elif currole == "WebSphereCustomRepository":
        CustomRepository.update(objid, curjsonobject, realm);
        roleProperties = curjsonobject.getJSONObject("roleProperties");
        id = roleProperties.optString("id", None);
        handledRepos.append(id);
      elif currole == "WebSphereFileRepository":
        FileRepository.update(objid, curjsonobject, realm);
        roleProperties = curjsonobject.getJSONObject("roleProperties");
        id = roleProperties.optString("id", None);
        handledRepos.append(id);
      elif currole == "WebSphereFederatedRepositoryAttributeMapping":
        # FederatedRepositoryAttributeMappings may only be updated (can't be created or deleted)
        FederatedRepositoryAttributeMapping.update(curjsonobject);
      elif currole == "WebSphereSupportedEntityType":
        # FederatedRepositoryAttributeMappings may only be updated (can't be created or deleted)
        SupportedEntityType.update(curjsonobject);
      else:
        propertyObject = Property.createObjIfRole(objid, curjsonobject, currole);

  # Compare previously existing repos to repos we created/updated to
  # determine if any repos need to be deleted
  if repos is not None and len(repos) > 0:
    for repo in repos:
      if len(repo) > 0:
        if repo.find("repositoryType=LDAP") != -1:
          name = repo[0:repo.find("=")];
          if name not in handledRepos:
            LDAPRepository.remove(realm, name);
        elif repo.find("repositoryType=Custom") != -1:
          name = repo[0:repo.find("=")];
          if name not in handledRepos:
            CustomRepository.remove(realm, name);
        elif repo.find("repositoryType=File") != -1:
          name = repo[0:repo.find("=")];
          if name not in handledRepos:
            FileRepository.remove(realm, name);
  Util.popPathElement('WIMUserRegistry');

def getWIMUserRegistry(objid):
  wimUserRegistry = Util.getAssociatedObjects(objid, "WIMUserRegistry");
  return wimUserRegistry;
