###
# Licensed Materials - Property of IBM* and/or HCL**
# (c) Copyright IBM Corporation 2015, 2017. All Rights Reserved.
# (c) Copyright HCL Technologies Ltd. 2018. All Rights Reserved.
#
# U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
# GSA ADP Schedule Contract with IBM Corp.
#
# * Trademark of International Business Machines
# ** Trademark of HCL Technologies Limited

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

__name_att__ = None;


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

  if parentrespath == "/":
    parentrespath = "";
  respath = "%(parentrespath)s/%(name)s" % { 'parentrespath':parentrespath, 'name':host }
  if not respath.startswith("/"):
    respath = "/" + respath;

  exportedObject = JSONObject();
  exportedObject.put("name", host);
  exportedObject.put("path", respath);
  exportedObject.put("teamMappings", JSONArray());
  exportedObject.put("inheritTeam", "true");
  exportedObject.put("description", "Discovered WebSphereLDAPServer");
  exportedObject.put("roleName", "WebSphereLDAPServer");

  roleProperties = JSONObject();

  # Get the config
  search = '[-id "' + name + '" -host ' + host +']';
  config = Util.getIdMgrLDAPServer(search);
  config = config[1:-1];
  validAttributes = ['host', 'securityDomainName', 'port', 'bindDN', 'bindPassword', 'authentication', 'referal',
                    'derefAliases', 'sslEnabled', 'connectionPool', 'connectTimeout', 'ldapServerType', 'sslConfiguration',
                    'certificateMapMode', 'certificateFilter', 'id'];
  attValueList = Util.getAttributeValueListFromString(config, validAttributes);
  for attValue in attValueList:
    attName = attValue[0];
    value = attValue[1];
    if attName != "id":
      Util.addToJsonIfNotNone(roleProperties, attName, value);

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

  # Get the LDAP Failover Servers
  listIdMgrLDAPBackupServersParams = '[-id "' + name + '" -primary_host ' + host + ']';
  failoverServers = Util.listIdMgrLDAPBackupServers(listIdMgrLDAPBackupServersParams);
  if len(failoverServers) > 0:
    failoverServersList = failoverServers.split("\n");
    for failoverServer in failoverServersList:
      if len(failoverServer) > 0:
        returndict = Util.createTypeFolder(respath, "LDAPFailoverServer", typeFolders);
        currespath = returndict['path'];
        if returndict.has_key('object'):
          extraObjects.append(returndict['object']);
        # failoverServer is in format {bluepages.com=389}
        failoverServer = failoverServer[1:-1];
        host = failoverServer[0:failoverServer.find("=")];
        port = failoverServer[failoverServer.find("=")+1:];
        Util.addAllFromExport(extraObjects, LDAPFailoverServer._export(currespath, host, port));

  # Get the LDAP 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, "LDAPCustomProperty", 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, LDAPCustomProperty._export(currespath, propName, propValue));

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

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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  host = roleProperties.optString("host", None);
  addIdMgrLDAPServerParams = '[-id "' + repo + '" -host ' + host;
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "securityDomainName", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "port", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "bindDN", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "bindPassword", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "authentication", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "referal", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "derefAliases", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "sslEnabled", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "connectionPool", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "connectTimeout", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "ldapServerType", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "sslConfiguration", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "certificateMapMode", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = Util.addParmIfNotNone(roleProperties, "certificateFilter", addIdMgrLDAPServerParams);
  addIdMgrLDAPServerParams = addIdMgrLDAPServerParams + "]";
  Log.debug("Running command to create LDAP server: AdminTask.addIdMgrLDAPServer(" + addIdMgrLDAPServerParams + ")");
  Util.addIdMgrLDAPServer(addIdMgrLDAPServerParams);

  for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
    currole = curjsonobject.getString('roleName');
    if currole == "WebSphereLDAPFailoverServer":
      LDAPFailoverServer.create(curjsonobject, repo, host);
    elif currole == "WebSphereLDAPCustomProperty":
      LDAPCustomProperty.create(curjsonobject, repo);
  Util.popPathElement('LDAPServer');

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

  roleProperties = jsonobject.getJSONObject("roleProperties");

  host = roleProperties.optString("host", None);
  # get list of LDAP Servers
  search = '[-id "' + repo + '"]';
  currentHost = Util.listIdMgrLDAPServers(search);

  if currentHost != host:
    create(jsonobject, repo);
  else:
    updateIdMgrLDAPServerParms = '[-id "' + repo + '" -host ' + host;
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "securityDomainName", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "port", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "bindDN", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "bindPassword", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "authentication", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "referal", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "derefAliases", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "sslEnabled", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "connectionPool", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "connectTimeout", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "ldapServerType", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "sslConfiguration", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "certificateMapMode", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = Util.addParmIfNotNone(roleProperties, "certificateFilter", updateIdMgrLDAPServerParms);
    updateIdMgrLDAPServerParms = updateIdMgrLDAPServerParms + "]";
    Log.debug("Running command to enable update LDAP Server: AdminTask.updateIdMgrLDAPServer(" + updateIdMgrLDAPServerParms + ")");
    Util.updateIdMgrLDAPServer(updateIdMgrLDAPServerParms);

    # Delete all LDAPFailoverServers
    listIdMgrLDAPBackupServersParams = '[-id "' + repo + '" -primary_host ' + host + ']';
    failoverServers = Util.listIdMgrLDAPBackupServers(listIdMgrLDAPBackupServersParams);
    if len(failoverServers) > 0:
      failoverServersList = failoverServers.split("\n");
      for failoverServer in failoverServersList:
        if len(failoverServer) > 0:
          failoverHost = failoverServer[1:failoverServer.find("=")];
          failoverPort = failoverServer[failoverServer.find("=")+1:-1];
          LDAPFailoverServer.remove(repo, host, failoverHost, failoverPort);

    # Delete all LDAPCustomProperties
    listIdMgrCustomPropertiesParams = '[-id "' + repo + '"]';
    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("=")];
          LDAPCustomProperty.remove(repo, propName);

    for curjsonobject in Util.getHighestChildrenWithRole(jsonobject.getJSONArray('children')):
      currole = curjsonobject.getString('roleName');
      if currole == "WebSphereLDAPFailoverServer":
        LDAPFailoverServer.create(curjsonobject, repo, host);
      elif currole == "WebSphereLDAPCustomProperty":
        LDAPCustomProperty.create(curjsonobject, repo);
  Util.popPathElement('LDAPServer');

