
package org.wso2.carbon.device.mgt.ios.services.impl;

import io.swagger.annotations.ApiParam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.common.license.mgt.License;
import org.wso2.carbon.device.mgt.ios.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.ios.exception.BadRequestException;
import org.wso2.carbon.device.mgt.ios.exception.IOSAgentException;
import org.wso2.carbon.device.mgt.ios.exception.UnexpectedServerErrorException;
import org.wso2.carbon.device.mgt.ios.services.DeviceTypeConfigurationService;
import org.wso2.carbon.device.mgt.ios.util.IOSServiceUtils;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;

@Path("/configuration")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurationService {
    private static Log log = LogFactory.getLog(DeviceTypeConfigurationServiceImpl.class);
    private static final String LICENSE_KEY = "iosEula";
    private static final String LANGUAGE_US = "en_US";
    private static final String CONTENT_TYPE_TEXT = "text";

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    @Override
    public Response getConfiguration( @HeaderParam("If-Modified-Since") String ifModifiedSince) {
        List<ConfigurationEntry> configs;
        PlatformConfiguration tenantConfiguration;
        String msg;
        try {
            tenantConfiguration = IOSServiceUtils.getDeviceManagementService().getConfiguration(
                    DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
            if (tenantConfiguration != null) {
                configs = tenantConfiguration.getConfiguration();
            } else {
                tenantConfiguration = new PlatformConfiguration();
                configs = new ArrayList<>();
            }
            ConfigurationEntry entry = new ConfigurationEntry();
            License license = IOSServiceUtils.getDeviceManagementService().getLicense(
                    DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS, LANGUAGE_US);

            if (license != null && configs != null) {
                entry.setContentType(CONTENT_TYPE_TEXT);
                entry.setName(LICENSE_KEY);
                entry.setValue(license.getText());
                configs.add(entry);
                tenantConfiguration.setConfiguration(configs);
            }
        } catch (DeviceManagementException e) {
            msg = "Error occurred while retrieving the iOS tenant configuration";
            log.error(msg, e);
            throw new UnexpectedServerErrorException(
                    new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
        }
        return Response.status(Response.Status.OK).entity(tenantConfiguration).build();
    }

    @POST
    @Override
    public Response configureSettings(PlatformConfiguration tenantConfiguration) {
        String msg;
        try {
            if (tenantConfiguration == null) {
                String errorMessage = "The payload of the iOS platform configuration is incorrect.";
                log.error(errorMessage);
                throw new BadRequestException(
                        new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
            }

            tenantConfiguration.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
            List<ConfigurationEntry> configs = tenantConfiguration.getConfiguration();
            ConfigurationEntry licenseEntry = null;
            for (ConfigurationEntry entry : configs) {
                if (LICENSE_KEY.equals(entry.getName())) {
                    License license = new License();
                    license.setName(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
                    license.setLanguage(LANGUAGE_US);
                    license.setVersion("1.0.0");
                    license.setText(entry.getValue().toString());
                    IOSServiceUtils.getDeviceManagementService().addLicense(DeviceManagementConstants.
                            MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS, license);
                    licenseEntry = entry;
                }
            }

            if (licenseEntry != null) {
                configs.remove(licenseEntry);
            }
            tenantConfiguration.setConfiguration(configs);
            IOSServiceUtils.getDeviceManagementService().saveConfiguration(tenantConfiguration);
        } catch (DeviceManagementException e) {
            msg = "Error occurred while saving the iOS tenant configuration";
            log.error(msg, e);
            throw new UnexpectedServerErrorException(
                    new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
        }
        return Response.status(Response.Status.CREATED).entity("IOS platform configuration saved successfully.").build();
    }

    @PUT
    @Produces({MediaType.APPLICATION_JSON})
    @Override
    public Response updateConfiguration(PlatformConfiguration tenantConfiguration) {
        String msg;
        try {
            if (tenantConfiguration == null) {
                String errorMessage = "The payload of the iOS platform configuration is incorrect.";
                log.error(errorMessage);
                throw new BadRequestException(
                        new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
            }

            tenantConfiguration.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
            List<ConfigurationEntry> configs = tenantConfiguration.getConfiguration();
            ConfigurationEntry licenseEntry = null;
            for (ConfigurationEntry entry : configs) {
                if (LICENSE_KEY.equals(entry.getName())) {
                    License license = new License();
                    license.setName(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
                    license.setLanguage(LANGUAGE_US);
                    license.setVersion("1.0.0");
                    license.setText(entry.getValue().toString());
                    IOSServiceUtils.getDeviceManagementService().addLicense(DeviceManagementConstants.
                            MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS, license);
                    licenseEntry = entry;
                }
            }

            if (licenseEntry != null) {
                configs.remove(licenseEntry);
            }
            tenantConfiguration.setConfiguration(configs);
            IOSServiceUtils.getDeviceManagementService().saveConfiguration(tenantConfiguration);
        } catch (DeviceManagementException e) {
            msg = "Error occurred while modifying configuration settings of Android platform";
            log.error(msg, e);
            throw new UnexpectedServerErrorException(
                    new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
        }
        return Response.status(Response.Status.OK).entity("IOS platform configuration updated successfully.").build();
    }

    @GET
    @Path("/license")
    @Produces(MediaType.TEXT_PLAIN)
    @Override
    public Response getLicense(
            @ApiParam(name = "If-Modified-Since",
                    value = "Validates if the requested variant has not been modified since the time specified",
                    required = false) @HeaderParam("If-Modified-Since") String ifModifiedSince)
            throws IOSAgentException {
        License license;
        try {
            license =
                    IOSServiceUtils.getDeviceManagementService().getLicense(
                            DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS,
                            DeviceManagementConstants.LanguageCodes.LANGUAGE_CODE_ENGLISH_US);
        } catch (DeviceManagementException e) {
            String msg = "Error occurred while retrieving the license configured for Android device enrolment";
            log.error(msg, e);
            throw new UnexpectedServerErrorException(
                    new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
        }
        return Response.status(Response.Status.OK).entity((license == null) ? null : license.getText()).build();
    }
}
