package org.wso2.carbon.device.mgt.ios.dep.utils;

import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.ios.dep.DEPConstants;
import org.wso2.carbon.device.mgt.ios.dep.beans.ServerToken;

import java.util.List;

/**
 * This class represents methods through which Apple DEP configurations which are in
 * registry can be retrieved.
 */
public class TokenUtils {

    private static final Log log = LogFactory.getLog(TokenUtils.class);

    /**
     * Retrieves Apple DEP configuration and set the appropriate values to a bean class.
     *
     * @return ServerToken which contains the Server Token details.
     * @throws DeviceManagementException if iOS DEP configuration is not able to retrieve.
     */
    public static ServerToken retrieveDEPConfiguration() throws DeviceManagementException {
        List<ConfigurationEntry> configs;
        PlatformConfiguration tenantConfiguration;
        tenantConfiguration = TokenUtils.getDeviceManagementService().
                getConfiguration(DeviceManagementConstants.
                        MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
        if (tenantConfiguration == null) {
            throw new DeviceManagementException("iOS DEP configuration is not saved.");
        } else {
            configs = tenantConfiguration.getConfiguration();
            ServerToken serverToken = new ServerToken();
            for (ConfigurationEntry config : configs) {
                switch (config.getName()) {
                    case DEPConstants.CONSUMER_KEY:
                        serverToken.setConsumerKey(config.getValue().toString());
                        break;
                    case DEPConstants.CONSUMER_SECRET:
                        serverToken.setConsumerSecret(config.getValue().toString());
                        break;
                    case DEPConstants.ACCESS_TOKEN:
                        serverToken.setAccessToken(config.getValue().toString());
                        break;
                    case DEPConstants.ACCESS_SECRET:
                        serverToken.setAccessSecret(config.getValue().toString());
                        break;
                    case DEPConstants.ACCESS_TOKEN_EXPIRY:
                        serverToken.setAccessTokenExpiry(config.getValue().toString());
                        break;
                    default:
                        break;
                }
            }
            return serverToken;
        }
    }

    /**
     * Initialize DeviceManagementProviderService.
     * @return DeviceManagementProviderService which has been initialized.
     * @throws IllegalStateException if iOS DEP configuration is not able to retrieve.
     */
    public static DeviceManagementProviderService getDeviceManagementService() {
        PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
        DeviceManagementProviderService deviceManagementService = (DeviceManagementProviderService)
                ctx.getOSGiService(DeviceManagementProviderService.class, null);
        if (deviceManagementService == null) {
            throw new IllegalStateException("DeviceManagementService is not initialized");
        }
        return deviceManagementService;
    }

    /**
     * When configuring a tenant for DEP, the agent's App ID from the store must be mentioned and
     * this will be pushed during enrollment to the device. This method will fetch the agent's
     * App Id from tenant configurations.
     *
     * @return iOS Agent's App Id.
     * @throws DeviceManagementException
     */
    public static String getAgentAppId() throws DeviceManagementException {
        List<ConfigurationEntry> configs;
        PlatformConfiguration tenantConfiguration;
        String agentAppId = null;
        tenantConfiguration = TokenUtils.getDeviceManagementService().
                getConfiguration(DeviceManagementConstants.
                        MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
        if (tenantConfiguration == null) {
            throw new DeviceManagementException("iOS DEP configuration is not saved.");
        } else {
            configs = tenantConfiguration.getConfiguration();
            for (ConfigurationEntry config : configs) {
                if (config.getName().equals(DEPConstants.AGENT_PACKAGE_NAME)) {
                    agentAppId = config.getValue().toString();
                }
            }
        }
        return agentAppId;
    }
}
