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

import com.google.gson.Gson;
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.operation.OperationPayloadConstants;
import org.wso2.carbon.device.mgt.ios.payload.plist.PListGenerator;

import java.util.HashMap;
import java.util.Map;
public abstract class PayloadOperation implements Operation {

    private static final String PAYLOAD_VERSION = "PayloadVersion";
    private static final String PAYLOAD_ORGANIZATION = "PayloadOrganization";
    private static final String PAYLOAD_TYPE = "PayloadType";
    private static final String PAYLOAD_IDENTIFIER = "PayloadIdentifier";
    private static final String PAYLOAD_DESCRIPTION = "PayloadDescription";
    private static final String PAYLOAD_DISPLAY_NAME = "PayloadDisplayName";
    private static final String PAYLOAD_REMOVAL_DISALLOWED = "PayloadRemovalDisallowed";
    private static final int PAYLOAD_VERSION_VALUE = 1;
    private PayloadProperties commandPayloadProperties;
    private Map<String, Object> commandMap;
    private String UUID;

    public enum PayloadType {

        CONFIGURATION("Configuration"),
        CELLULAR("com.apple.cellular"),
        APN("com.apple.apn.managed"),
        RESTRICTION("com.apple.applicationaccess"),
        WIFI("com.apple.wifi.managed"),
        VPN("com.apple.vpn.managed"),
        PER_APP_VPN("com.apple.vpn.managed.applayer"),
        APP_TO_PER_APP_VPN_MAPPING("com.apple.vpn.managed.appmapping"),
        LDAP("com.apple.ldap.account"),
        CALDAV("com.apple.caldav.account"),
        CALENDAR_SUBSCRIPTION("com.apple.subscribedcalendar.account"),
        PASSCODE_POLICY("com.apple.mobiledevice.passwordpolicy"),
        EMAIL("com.apple.mail.managed"),
        AIR_PLAY("com.apple.airplay"),
        WEB_CLIP("com.apple.webClip.managed"),
        APP_LOCK("com.apple.app.lock"),
        DOMAIN("com.apple.domains");

        private String payloadType;

        private PayloadType(String payloadType) {
            this.payloadType = payloadType;
        }

        public String getPayloadType() {
            return payloadType;
        }

    }

    public void setUUID(String UUID) {
        this.UUID = UUID;
    }

    public final String getUUID() {
        return UUID;
    }

    public static String generateOperationPayload(PayloadOperationWrapper payloadOperationWrapper, String UUID)
            throws PListException {

        PayloadProperties payloadProperties = payloadOperationWrapper.getPayloadProperties();

        Map<String, Object> generalMap = new HashMap<String, Object>();
        generalMap.put(PAYLOAD_VERSION, PAYLOAD_VERSION_VALUE);
        generalMap.put(OperationPayloadConstants.PAYLOAD_UUID, UUID);
        generalMap.put(PAYLOAD_ORGANIZATION, payloadProperties.getTenantName());
        generalMap.put(PAYLOAD_TYPE, PayloadType.CONFIGURATION.getPayloadType());
        generalMap.put(PAYLOAD_IDENTIFIER, payloadProperties.getPayloadIdentifier());
        generalMap.put(PAYLOAD_DESCRIPTION, payloadProperties.getPayloadDescription());
        generalMap.put(PAYLOAD_DISPLAY_NAME, payloadProperties.getPayloadDisplayName());
        generalMap.put(PAYLOAD_REMOVAL_DISALLOWED, payloadProperties.isPayloadRemoveDisallowed());

        generalMap.put(OperationPayloadConstants.PAYLOAD_CONTENT, payloadOperationWrapper.getPayload());

        return new PListGenerator().generatePayload(generalMap);
    }

    public void populateCommandPayloadElements(PayloadProperties payloadProperties) {
        this.commandPayloadProperties = payloadProperties;

        Map<String, Object> commandMap = new HashMap<String, Object>();
        commandMap.put(PAYLOAD_VERSION, PAYLOAD_VERSION_VALUE);
        commandMap.put(OperationPayloadConstants.PAYLOAD_UUID, UUID);
        commandMap.put(PAYLOAD_ORGANIZATION, payloadProperties.getTenantName());
        commandMap.put(PAYLOAD_TYPE, payloadProperties.getPayloadType());
        commandMap.put(PAYLOAD_IDENTIFIER, payloadProperties.getPayloadIdentifier());
        commandMap.put(PAYLOAD_DESCRIPTION, payloadProperties.getPayloadDescription());
        commandMap.put(PAYLOAD_DISPLAY_NAME, payloadProperties.getPayloadDisplayName());
        commandMap.put(PAYLOAD_REMOVAL_DISALLOWED, payloadProperties.isPayloadRemoveDisallowed());

        this.commandMap = commandMap;
    }

    @Override
    public void validateRequest() throws ProfileConfigurationException {

        if(commandPayloadProperties.getTenantName() == null) {
            throw new ProfileConfigurationException("Tenant name is empty");
        } else if(commandPayloadProperties.getPayloadType() == null) {
            throw new ProfileConfigurationException("Payload type is empty");
        } else if(commandPayloadProperties.getPayloadIdentifier() == null) {
            throw new ProfileConfigurationException("Payload identifier is empty");
        } else if(commandPayloadProperties.getPayloadDescription() == null) {
            throw new ProfileConfigurationException("Payload description is empty");
        } else if(commandPayloadProperties.getPayloadDisplayName() == null) {
            throw new ProfileConfigurationException("Payload display name is empty");
        }
    }

    public String toJSON() throws ProfileConfigurationException {
           Gson gson = new Gson();
           return gson.toJson(this);
    }

    public Map<String, Object> getCommandMap() {
        return commandMap;
    }
}
