package org.wso2.carbon.device.mgt.ios.payload.operation;

import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.ios.payload.beans.LDAP;
import org.wso2.carbon.device.mgt.ios.payload.beans.LDAPSearchSetting;
import org.wso2.carbon.device.mgt.ios.payload.beans.PayloadOperation;
import org.wso2.carbon.device.mgt.ios.payload.dto.PayloadOperationWrapper;
import org.wso2.carbon.device.mgt.ios.payload.dto.PayloadProperties;
import org.wso2.carbon.device.mgt.ios.payload.exception.PListException;
import org.wso2.carbon.device.mgt.ios.payload.exception.ProfileConfigurationException;
import org.wso2.carbon.device.mgt.ios.payload.util.OperationUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LDAPOperations {

    private static final String PAYLOAD_DISPLAY_NAME = "LDAP Configurations";
    private static final String PAYLOAD_DESCRIPTION = "LDAP Configurations for %s";
    private static final String LDAP_SEARCH_SETTING_DESCRIPTION = "LDAPSearchSettingDescription";
    private static final String LDAP_SEARCH_SETTING_SEARCH_BASE = "LDAPSearchSettingSearchBase";
    private static final String LDAP_SEARCH_SETTING_SCOPE = "LDAPSearchSettingScope";
    private static final String LDAP_SEARCH_SETTINGS = "LDAPSearchSettings";
    private static final String LDAP_ACCOUNT_DESCRIPTION = "LDAPAccountDescription";
    private static final String LDAP_ACCOUNT_HOST_NAME = "LDAPAccountHostName";
    private static final String LDAP_ACCOUNT_USE_SSL = "LDAPAccountUseSSL";
    private static final String LDAP_ACCOUNT_USERNAME = "LDAPAccountUserName";
    private static final String LDAP_ACCOUNT_PASSWORD = "LDAPAccountPassword";

    public PayloadOperationWrapper createLDAPPayload(LDAP ldap) throws PListException, ProfileConfigurationException {

        PayloadProperties payloadProperties = generateCommonElements(ldap,
                OperationUtils.getTenantNameFromOperationID(), OperationUtils.isPayloadRemoveDisallowedForTenant());

        ldap.validateRequest();

        List<LDAPSearchSetting> listLDAPSearchSettings = ldap.getLdapSearchSettings();
        List<Object> searchSettingsList = new ArrayList<Object>();

        if (listLDAPSearchSettings != null) {
            for (LDAPSearchSetting ldapSearchSetting : listLDAPSearchSettings) {

                Map<String, Object> searchSettingsMap = new HashMap<String, Object>();
                searchSettingsMap.put(LDAP_SEARCH_SETTING_DESCRIPTION,
                        ldapSearchSetting.getSearchSettingDescription());
                searchSettingsMap.put(LDAP_SEARCH_SETTING_SEARCH_BASE,
                        ldapSearchSetting.getSearchSettingSearchBase());
                searchSettingsMap.put(LDAP_SEARCH_SETTING_SCOPE,
                        ldapSearchSetting.getSearchSettingScope().toString());

                searchSettingsList.add(searchSettingsMap);
            }
        }

        Map<String, Object> commandMap = ldap.getCommandMap();
        commandMap.put(LDAP_SEARCH_SETTINGS, searchSettingsList);
        commandMap.put(LDAP_ACCOUNT_DESCRIPTION, ldap.getAccountDescription());
        commandMap.put(LDAP_ACCOUNT_HOST_NAME, ldap.getAccountHostName());
        commandMap.put(LDAP_ACCOUNT_USE_SSL, ldap.getAccountUseSSL());
        if(ldap.getAccountUsername() != null && !ldap.getAccountUsername().isEmpty()) {
            commandMap.put(LDAP_ACCOUNT_USERNAME, ldap.getAccountUsername());
        } else {
            String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
            if (username != null) {
                commandMap.put(LDAP_ACCOUNT_USERNAME, username);
            }
        }

        if(ldap.getAccountPassword() != null && !ldap.getAccountPassword().isEmpty()) {
            commandMap.put(LDAP_ACCOUNT_PASSWORD, ldap.getAccountPassword());
        }

        List<Object> payloadContent = new ArrayList<Object>();
        payloadContent.add(commandMap);

        PayloadOperationWrapper payloadOperationWrapper = new PayloadOperationWrapper();
        payloadOperationWrapper.setPayload(payloadContent);
        payloadOperationWrapper.setPayloadProperties(payloadProperties);

        return payloadOperationWrapper;
    }

    private PayloadProperties generateCommonElements(LDAP ldap, String tenantName,
                                        boolean payloadRemoveDisallowed) {

        PayloadProperties payloadProperties = new PayloadProperties();
        payloadProperties.setTenantName(tenantName);
        payloadProperties.setPayloadType(PayloadOperation.PayloadType.LDAP.getPayloadType());
        payloadProperties.setPayloadIdentifier(ldap.getUUID());
        payloadProperties.setPayloadDisplayName(PAYLOAD_DISPLAY_NAME);
        payloadProperties.setPayloadDescription(String.format(PAYLOAD_DESCRIPTION, tenantName));
        payloadProperties.setPayloadRemoveDisallowed(payloadRemoveDisallowed);

        ldap.populateCommandPayloadElements(payloadProperties);

        return payloadProperties;
    }

}
