#- 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('FileRepository')

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

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

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

  if config.find("adapterClassName=") != -1:
    adapterClassName = config[config.find("adapterClassName=")+17:config.find(", ", config.find("adapterClassName=")+17)];
    Util.addToJsonIfNotNone(roleProperties, "adapterClassName", adapterClassName);
  if config.find("loginProperties=") != -1:
    loginProperties = config[config.find("loginProperties=[")+17:config.find("]",config.find("loginProperties=[")+17)];
    loginProperties = loginProperties.replace(", ", ";");
    Util.addToJsonIfNotNone(roleProperties, "loginProperties", loginProperties);
  if config.find("isExtIdUnique=") != -1:
    isExtIdUnique = config[config.find("isExtIdUnique=")+14:config.find(", ", config.find("isExtIdUnique=")+14)];
    Util.addToJsonIfNotNone(roleProperties, "isExtIdUnique", isExtIdUnique);
  if config.find("supportTransactions=") != -1:
    supportTransactions = config[config.find("supportTransactions=")+20:config.find(", ", config.find("supportTransactions=")+20)];
    Util.addToJsonIfNotNone(roleProperties, "supportTransactions", supportTransactions);
  if config.find("messageDigestAlgorithm=") != -1:
    messageDigestAlgorithm = config[config.find("messageDigestAlgorithm=")+23:config.find(", ", config.find("messageDigestAlgorithm=")+23)];
    Util.addToJsonIfNotNone(roleProperties, "messageDigestAlgorithm", messageDigestAlgorithm);
  if config.find("supportExternalName=") != -1:
    supportExternalName = config[config.find("supportExternalName=")+20:config.find(", ", config.find("supportExternalName=")+20)];
    Util.addToJsonIfNotNone(roleProperties, "supportExternalName", supportExternalName);
  if config.find("fileName=") != -1:
    fileName = config[config.find("fileName=")+9:config.find(", ", config.find("fileName=")+9)];
    Util.addToJsonIfNotNone(roleProperties, "fileName", fileName);
  if config.find("supportAsyncMode=") != -1:
    supportAsyncMode = config[config.find("supportAsyncMode=")+17:config.find(", ", config.find("supportAsyncMode=")+17)];
    Util.addToJsonIfNotNone(roleProperties, "supportAsyncMode", supportAsyncMode);
  if config.find("supportSorting=") != -1:
    supportSorting = config[config.find("supportSorting=")+15:config.find(", ", config.find("supportSorting=")+15)];
    Util.addToJsonIfNotNone(roleProperties, "supportSorting", supportSorting);
  if config.find("supportPaging=") != -1:
    supportPaging = config[config.find("supportPaging=")+14:config.find(", ", config.find("supportPaging=")+14)];
    Util.addToJsonIfNotNone(roleProperties, "supportPaging", supportPaging);
  if config.find("saltLength=") != -1:
    saltLength = config[config.find("saltLength=")+11:config.find(", ", config.find("saltLength=")+11)];
    Util.addToJsonIfNotNone(roleProperties, "saltLength", saltLength);
  if config.find("baseDirectory=") != -1:
    baseDirectory = config[config.find("baseDirectory=")+14:config.find(", ", config.find("baseDirectory=")+14)];
    Util.addToJsonIfNotNone(roleProperties, "baseDirectory", baseDirectory);

  # 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('FileRepository');
  return result;

def update(parentid, jsonobject, realm):
  Util.pushPathElement('FileRepository')
  if not jsonobject.has("roleProperties"):
    raise Exception("FileRepository 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 File 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
      updateIdMgrRepositoryParams = "[-id " + id;
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "adapterClassName", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "loginProperties", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "isExtIdUnique", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportTransactions", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportExternalName", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportAsyncMode", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportSorting", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportPaging", updateIdMgrRepositoryParams);
      updateIdMgrRepositoryParams = updateIdMgrRepositoryParams + "]";
      Log.debug("Running command to update File Repository: AdminTask.updateIdMgrRepository(" + updateIdMgrRepositoryParams + ")");
      Util.updateIdMgrRepository(updateIdMgrRepositoryParams);
      updateIdMgrFileRepositoryParams = "[-id " + id;
      updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "messageDigestAlgorithm", updateIdMgrFileRepositoryParams);
      updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "saltLength", updateIdMgrFileRepositoryParams);
      updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "baseDirectory", updateIdMgrFileRepositoryParams);
      updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "fileName", updateIdMgrFileRepositoryParams);
      updateIdMgrFileRepositoryParams = updateIdMgrFileRepositoryParams + "]";
      Log.debug("Running command to update File Repository: AdminTask.updateIdMgrFileRepository(" + updateIdMgrFileRepositoryParams + ")");
      Util.updateIdMgrFileRepository(updateIdMgrFileRepositoryParams);

      # 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 File 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 File 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 file realm base entry: AdminTask.deleteIdMgrRealmBaseEntry(" + deleteIdMgrRealmBaseEntryParams + ")");
          Util.deleteIdMgrRealmBaseEntry(deleteIdMgrRealmBaseEntryParams);
          deleteIdMgrRepositoryBaseEntryParams = "[-id " + id + " -name " + currentBaseEntries[0] + "]";
          Log.debug("Running command to remove file 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('FileRepository');

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

  # Run the AdminTask.createIdMgrFileRepository command to create a repository
  # example: AdminTask.createIdMgrFileRepository('[-id Custom1 -adapterClassName com.ibm.ws.wim.adapter.file.was.FileAdapter]')
  id = roleProperties.optString("id", None);
  adapterClassName = roleProperties.optString("adapterClassName", None);
  createIdMgrFileRepositoryParams = "[-id " + id + " -adapterClassName " + adapterClassName;
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "isExtIdUnique", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportTransactions", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "messageDigestAlgorithm", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportExternalName", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "fileName", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportAsyncMode", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportSorting", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "supportPaging", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "saltLength", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "baseDirectory", createIdMgrFileRepositoryParams);
  createIdMgrFileRepositoryParams = createIdMgrFileRepositoryParams + "]";
  Log.debug("Running command to create File Repository: AdminTask.createIdMgrFileRepository(" + createIdMgrFileRepositoryParams + ")");
  Util.createIdMgrFileRepository(createIdMgrFileRepositoryParams);

  # 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 File Repository: AdminTask.updateIdMgrRepository(" + updateIdMgrRepositoryParams + ")");
    Util.updateIdMgrRepository(updateIdMgrRepositoryParams);
    # after updating loginProperties, WAS does an update of some properties
    updateIdMgrFileRepositoryParams = "[-id " + id;
    updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "messageDigestAlgorithm", updateIdMgrFileRepositoryParams);
    updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "saltLength", updateIdMgrFileRepositoryParams);
    updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "baseDirectory", updateIdMgrFileRepositoryParams);
    updateIdMgrFileRepositoryParams = Util.addParmIfNotNone(roleProperties, "fileName", updateIdMgrFileRepositoryParams);
    updateIdMgrFileRepositoryParams = updateIdMgrFileRepositoryParams + "]";
    Log.debug("Running command to update File Repository: AdminTask.updateIdMgrFileRepository(" + updateIdMgrFileRepositoryParams + ")");
    Util.updateIdMgrFileRepository(updateIdMgrFileRepositoryParams);

  # 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 File 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('FileRepository');

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 file 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 file 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 file repository: AdminTask.deleteIdMgrRepository(" + deleteIdMgrRepositoryParams + ")");
  Util.deleteIdMgrRepository(deleteIdMgrRepositoryParams);

