#- Licensed Materials - Property of IBM Corp.
#- IBM UrbanCode Deploy
#- (c) Copyright IBM Corporation 2015. All Rights Reserved.
#-
#- U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
#- GSA ADP Schedule Contract with IBM Corp.

from org.codehaus.jettison.json import JSONObject, JSONArray
import sys;
from WASConfLog import Log;
from utilities import Util
from RepositoryCustomProperty import RepositoryCustomProperty

__name_att__ = None;


def _export(parentrespath, name):
  Util.pushPathElement('CustomRepository')

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

  roleProperties = JSONObject();
  Util.addToJsonIfNotNone(roleProperties, "id", name);

  # get the config
  search = "[-id " + name + "]";
  config = Util.getIdMgrRepository(search);

  adapterClassName = config[config.find("adapterClassName=")+17:config.find(", ", config.find("adapterClassName=")+17)];
  Util.addToJsonIfNotNone(roleProperties, "adapterClassName", adapterClassName);
  if config.find("loginProperties=") >= 0:
    loginProperties = config[config.find("loginProperties=[")+17:config.find("]",config.find("loginProperties=[")+17)];
    loginProperties = loginProperties.replace(", ", ";");
    Util.addToJsonIfNotNone(roleProperties, "loginProperties", loginProperties);

  # get the Base Entries and store it as an attribute
  baseEntries = Util.listIdMgrRepositoryBaseEntries(search);
  Util.addToJsonIfNotNone(roleProperties, "baseEntries", baseEntries);

  exportedObject.put("roleProperties", roleProperties);
  result = { 'object': exportedObject, 'respath':respath }
  extraObjects = [];
  typeFolders = {};

  # Get the custom properties
  listIdMgrCustomPropertiesParams = "[-id " + name + "]";
  customProperties = Util.listIdMgrCustomProperties(listIdMgrCustomPropertiesParams);
  # customProperties is in format: {Holiday=Independence Day, TodayIs=Thursday, America=1776}
  if len(customProperties) > 0:
    customProperties = customProperties[1:-1];
    customPropertiesList = customProperties.split(", ");
    for customProperty in customPropertiesList:
      if len(customProperty) > 0:
        returndict = Util.createTypeFolder(respath, "RepositoryCustomProperty", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          extraObjects.append(returndict['object']);
        propName = customProperty[0:customProperty.find("=")];
        propValue = customProperty[customProperty.find("=")+1:]
        Util.addAllFromExport(extraObjects, RepositoryCustomProperty._export(currespath, propName, propValue));

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

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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  # The command AdminTask.configureAdminWIMUserRegistry can take several parameters, but
  # we are only specifying -realName and -verifyRegistry (we will not automatically generate server identity).
  # -verifyRegistry will be set to false so the configuration will be set regardless of if the system can
  # reach the user registry or not
  configureAdminWIMUserRegistryParams = "[-realmName " + realm + " -verifyRegistry false]";
  Log.debug("Running command to enable editing of WIMUserRegistry: AdminTask.configureAdminWIMUserRegistry(" + configureAdminWIMUserRegistryParams + ")");
  Util.configureAdminWIMUserRegistry(configureAdminWIMUserRegistryParams);

  id = roleProperties.optString("id", None);
  # get list of repositories
  repolist = Util.listIdMgrRepositories();
  if repolist != None and len(repolist) > 0:
    findTarget = id + "=";
    if repolist.find(findTarget) == -1:
      create(roleProperties, jsonobject, realm);
    else:
      # Update the existing Custom Repository
      # First, need to remove loginProperties value (will add the new value later)
      updateIdMgrRepositoryParams = "[-id " + id + " -loginProperties [\"\"]]";
      Log.debug("Running command to update Custom Repository: AdminTask.updateIdMgrRepository(" + updateIdMgrRepositoryParams + ")");
      Util.updateIdMgrRepository(updateIdMgrRepositoryParams);
      # Now, update the properties
      adapterClassName = roleProperties.optString("adapterClassName", None);
      loginProperties = roleProperties.optString("loginProperties", None);
      if loginProperties != None and len(loginProperties) > 0:
        updateIdMgrRepositoryParams = "[-id " + id + " -adapterClassName " + adapterClassName + " -loginProperties " + loginProperties + "]";
      else:
        updateIdMgrRepositoryParams = "[-id " + id + " -adapterClassName " + adapterClassName + "]";
      Log.debug("Running command to update Custom Repository: AdminTask.updateIdMgrRepository(" + updateIdMgrRepositoryParams + ")");
      Util.updateIdMgrRepository(updateIdMgrRepositoryParams);

      # Get the current base entries and see if they need to be updated
      # When updating, you need to add the new values before deleting the old values
      listIdMgrRepositoryBaseEntriesParams = "[-id " + id + "]";
      currentBaseEntries = Util.listIdMgrRepositoryBaseEntries(listIdMgrRepositoryBaseEntriesParams);
      desiredBaseEntries = roleProperties.optString("baseEntries", None);
      if currentBaseEntries != desiredBaseEntries:
        currentBaseEntries = Util.interpretBaseEntries(currentBaseEntries);
        desiredBaseEntries = Util.interpretBaseEntries(desiredBaseEntries);
        if currentBaseEntries[0] == desiredBaseEntries[0]:
          # only update the repository base entries
          updateIdMgrRepositoryBaseEntryParams = "[-id " + id + " -name " + desiredBaseEntries[0] + " -nameInRepository " + desiredBaseEntries[1] + "]";
          Log.debug("Running command to update Cutom Repository's base entries: AdminTask.updateIdMgrRepositoryBaseEntry(" + updateIdMgrRepositoryBaseEntryParams + ")");
          Util.updateIdMgrRepositoryBaseEntry(updateIdMgrRepositoryBaseEntryParams);
        else:
          # update repository and realm base entries
          addIdMgrRepositoryBaseEntryParams = "[-id " + id + " -name " + desiredBaseEntries[0] + " -nameInRepository " + desiredBaseEntries[1] + "]";
          Log.debug("Running command to update Custom Repository's base entries: AdminTask.addIdMgrRepositoryBaseEntry(" + addIdMgrRepositoryBaseEntryParams + ")");
          Util.addIdMgrRepositoryBaseEntry(addIdMgrRepositoryBaseEntryParams);
          addIdMgrRealmBaseEntryParms = "[-name " + realm + " -baseEntry " + desiredBaseEntries[0] + "]";
          Log.debug("Running command to add realm base entry: AdminTask.addIdMgrRealmBaseEntry(" + addIdMgrRealmBaseEntryParms + ")");
          Util.addIdMgrRealmBaseEntry(addIdMgrRealmBaseEntryParms);
          deleteIdMgrRealmBaseEntryParams = "[-name " + realm + " -baseEntry " + currentBaseEntries[0] + "]";
          Log.debug("Running command to remove custom realm base entry: AdminTask.deleteIdMgrRealmBaseEntry(" + deleteIdMgrRealmBaseEntryParams + ")");
          Util.deleteIdMgrRealmBaseEntry(deleteIdMgrRealmBaseEntryParams);
          deleteIdMgrRepositoryBaseEntryParams = "[-id " + id + " -name " + currentBaseEntries[0] + "]";
          Log.debug("Running command to remove custom repository base entry: AdminTask.deleteIdMgrRepositoryBaseEntry(" + deleteIdMgrRepositoryBaseEntryParams + ")");
          Util.deleteIdMgrRepositoryBaseEntry(deleteIdMgrRepositoryBaseEntryParams);

      # Delete all RepositoryCustomProperties
      listIdMgrCustomPropertiesParams = "[-id " + id + "]";
      customProperties = Util.listIdMgrCustomProperties(listIdMgrCustomPropertiesParams);
      # customProperties is in format: {Holiday=Independence Day, TodayIs=Thursday, America=1776}
      if len(customProperties) > 0:
        customProperties = customProperties[1:-1];
        customPropertiesList = customProperties.split(", ");
        for customProperty in customPropertiesList:
          if len(customProperty) > 0:
            propName = customProperty[0:customProperty.find("=")];
            RepositoryCustomProperty.remove(id, propName);

      for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
        currole = curjsonobject.getString('roleName');
        if currole == "WebSphereRepositoryCustomProperty":
          RepositoryCustomProperty.create(curjsonobject, id);

  Util.popPathElement('CustomRepository');

def create(roleProperties, jsonobject, realm):
  Util.pushPathElement('CustomRepository')

  # Run the AdminTask.createIdMgrCustomRepository command to create a repository
  # example: AdminTask.createIdMgrCustomRepository('[-id Custom1 -adapterClassName com.ibm.ws.wim.adapter.ldap.LdapAdapter]')
  id = roleProperties.optString("id", None);
  adapterClassName = roleProperties.optString("adapterClassName", None);
  createIdMgrCustomRepositoryParams = "[-id " + id + " -adapterClassName " + adapterClassName + "]";
  Log.debug("Running command to create Custom Repository: AdminTask.createIdMgrCustomRepository(" + createIdMgrCustomRepositoryParams + ")");
  Util.createIdMgrCustomRepository(createIdMgrCustomRepositoryParams);

  # if there are login properties, need to use the updateIdMgrRepository command to update the repository
  loginProperties = roleProperties.optString("loginProperties", None);
  if loginProperties != None and len(loginProperties) > 0:
    updateIdMgrRepositoryParams = "[-id " + id + " -adapterClassName " + adapterClassName + " -loginProperties " + loginProperties + "]";
    Log.debug("Running command to update Custom Repository: AdminTask.updateIdMgrRepository(" + updateIdMgrRepositoryParams + ")");
    Util.updateIdMgrRepository(updateIdMgrRepositoryParams);

  # update the base entries, if needed
  baseEntries = roleProperties.optString("baseEntries", None);
  if baseEntries != None and len(baseEntries) > 0:
    baseEntries = Util.interpretBaseEntries(baseEntries);
    addIdMgrRepositoryBaseEntryParams = "[-id " + id + " -name " + baseEntries[0] + " -nameInRepository " + baseEntries[1] + "]";
    Log.debug("Running command to update Custom Repository's base entries: AdminTask.addIdMgrRepositoryBaseEntry(" + addIdMgrRepositoryBaseEntryParams + ")");
    Util.addIdMgrRepositoryBaseEntry(addIdMgrRepositoryBaseEntryParams);
    addIdMgrRealmBaseEntryParms = "[-name " + realm + " -baseEntry " + baseEntries[0] + "]";
    Log.debug("Running command to add realm base entry: AdminTask.addIdMgrRealmBaseEntry(" + addIdMgrRealmBaseEntryParms + ")");
    Util.addIdMgrRealmBaseEntry(addIdMgrRealmBaseEntryParms);

  if jsonobject.has('children'):
    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString('roleName');
      if currole == "WebSphereRepositoryCustomProperty":
        RepositoryCustomProperty.create(curjsonobject, id);
  Util.popPathElement('CustomRepository');

def remove(realm, repo):
  # Remove each base entry
  listIdMgrRepositoryBaseEntriesParams = "[-id " + repo + "]";
  baseEntries = Util.listIdMgrRepositoryBaseEntries(listIdMgrRepositoryBaseEntriesParams);
  # Remove brackets, if needed
  if baseEntries.startswith("{"):
    baseEntries = baseEntries[1:-1];
  baseEntriesList = baseEntries.split(", ");
  j = 1;
  for baseEntry in baseEntriesList:
    baseEntry = Util.interpretBaseEntries(baseEntry);
    # Remove the realm base entry
    deleteIdMgrRealmBaseEntryParams = "[-name " + realm + " -baseEntry " + baseEntry[0] + "]";
    Log.debug("Running command to remove custom realm base entry: AdminTask.deleteIdMgrRealmBaseEntry(" + deleteIdMgrRealmBaseEntryParams + ")");
    Util.deleteIdMgrRealmBaseEntry(deleteIdMgrRealmBaseEntryParams);

    # We need to remove all of the repository base entries EXCEPT for the last one
    # (there must always be one base entry remaining)
    if j < len(baseEntriesList):
      deleteIdMgrRepositoryBaseEntryParams = "[-id " + repo + " -name " + baseEntry[0] + "]";
      Log.debug("Running command to remove custom repository base entry: AdminTask.deleteIdMgrRepositoryBaseEntry(" + deleteIdMgrRepositoryBaseEntryParams + ")");
      Util.deleteIdMgrRepositoryBaseEntry(deleteIdMgrRepositoryBaseEntryParams);
    j = j + 1;

  # Finally, delete the repository itself
  deleteIdMgrRepositoryParams = "[-id " + repo + "]";
  Log.debug("Running command to delete custom repository: AdminTask.deleteIdMgrRepository(" + deleteIdMgrRepositoryParams + ")");
  Util.deleteIdMgrRepository(deleteIdMgrRepositoryParams);

