package org.wso2.carbon.device.mgt.ios.core.util;

import org.apache.commons.codec.binary.Base64;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.ios.core.exception.TenantConfigurationException;
import org.wso2.carbon.device.mgt.ios.core.internal.IOSEnrollmentServiceHolder;
import org.wso2.carbon.device.mgt.ios.payload.dto.CertificateAttributes;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TenantUtils {

    private static final String CONFIG_COUNTRY = "configCountry";
    private static final String CONFIG_STATE = "configState";
    private static final String CONFIG_LOCALITY = "configLocality";
    private static final String CONFIG_ORGANIZATION = "configOrganization";
    private static final String CONFIG_ORGANIZATION_UNIT = "configOrganizationUnit";
    private static final String ORG_DISPLAY_NAME = "organizationDisplayName";
    private static final String MDM_CERT_PASSWORD = "MDMCertPassword";
    private static final String MDM_CERT_TOPIC_ID = "MDMCertTopicID";
    private static final String APNS_CERT_PASSWORD = "APNSCertPassword";
    private static final String MDM_CERT = "MDMCert";
    private static final String APNS_CERT = "APNSCert";
    private static final String MDM_MODE = "iOSConfigMDMMode";
    private static final String APNS_MODE = "iOSConfigAPNSMode";
    private static final String PREPENDED_DATA = "data:application/x-pkcs12;base64,";

    private Map<String, String> tenantConfigurations;

    public TenantUtils() throws DeviceManagementException, TenantConfigurationException {

        PlatformConfiguration tenantConfiguration = IOSEnrollmentServiceHolder.getInstance().getDeviceManagementService().
                getConfiguration(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
        if (tenantConfiguration == null) {
            throw new TenantConfigurationException("iOS Platform configuration is null. Please verify that the iOS platform configuration is set through DeviceMgt WebApp.");
        }

        List<ConfigurationEntry> configurationEntries = tenantConfiguration.getConfiguration();
        if (configurationEntries == null) {
            throw new DeviceManagementException("iOS Platform configuration is null. Please verify that the iOS platform configuration is set through DeviceMgt WebApp.");
        }

        tenantConfigurations = new HashMap<String, String>();
        for (ConfigurationEntry configurationEntry : configurationEntries) {
            String configurationValue = configurationEntry.getValue() != null ?
                    configurationEntry.getValue().toString() : "";

            tenantConfigurations.put(configurationEntry.getName(), configurationValue);
        }
    }

    public CertificateAttributes getCertificateAttributes() {

        CertificateAttributes certificateAttributes = new CertificateAttributes();
        certificateAttributes.setCountry(tenantConfigurations.get(CONFIG_COUNTRY));
        certificateAttributes.setState(tenantConfigurations.get(CONFIG_STATE));
        certificateAttributes.setLocality(tenantConfigurations.get(CONFIG_LOCALITY));
        certificateAttributes.setOrganization(tenantConfigurations.get(CONFIG_ORGANIZATION));
        certificateAttributes.setOrganizationUnit(tenantConfigurations.get(CONFIG_ORGANIZATION_UNIT));

        return certificateAttributes;
    }

    public String getTopicID() {
        return tenantConfigurations.get(MDM_CERT_TOPIC_ID);
    }

    public String getTenantDisplayName() {
        return tenantConfigurations.get(ORG_DISPLAY_NAME);
    }

    public InputStream getTenantMDMCertificate() {
        String extractedCertificate = null;
        ByteArrayInputStream certificateStream = null;
        String certificate = tenantConfigurations.get(MDM_CERT);
        if (certificate != null) {
            extractedCertificate = certificate.split(PREPENDED_DATA)[1];
        }
        if (extractedCertificate != null) {
            byte[] decoded = Base64.decodeBase64(extractedCertificate);
            certificateStream = new ByteArrayInputStream(decoded);
        }

        return certificateStream;
    }

    public String getTenantMDMCertificatePassword() {
        return tenantConfigurations.get(MDM_CERT_PASSWORD);
    }

    public InputStream getTenantAPNSCertificate() {
        String extractedCertificate = null;
        ByteArrayInputStream certificateStream = null;
        String certificate = tenantConfigurations.get(APNS_CERT);
        if (certificate != null) {
            extractedCertificate = certificate.split(PREPENDED_DATA)[1];
        }
        if (extractedCertificate != null) {
            byte[] decoded = Base64.decodeBase64(extractedCertificate);
            certificateStream = new ByteArrayInputStream(decoded);
        }

        return certificateStream;
    }

    public String getTenantAPNSCertificatePassword() {
        return tenantConfigurations.get(APNS_CERT_PASSWORD);
    }

    public String getAPNSMode() {
        return tenantConfigurations.get(APNS_MODE);
    }

    public String getMDMMode() {
        return tenantConfigurations.get(MDM_MODE);
    }

    public static String getTenantDomainName(){
        return PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
    }
}
