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

import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.ios.api.utils.util.*;
import org.wso2.carbon.device.mgt.ios.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.ios.exception.*;

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

public class DeviceUtils {

    private static final String DEVICE_ID_NOT_FOUND = "Device Id not found for device found at %s";
    private static final String DEVICE_ID_SERVICE_NOT_FOUND =
            "Issue in retrieving device management service instance for device found at %s";
    private static final String COMMA_SEPARATION_PATTERN = ", ";

    public DeviceIdentifier fetchDeviceIdentifierInstance(String deviceId) {

        String msg;
        if (deviceId == null || deviceId.trim().isEmpty()) {
            msg = "Empty device id received";
            throw new BadRequestException(
                    new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(msg).build());
        }

        DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
        deviceIdentifier.setId(deviceId);
        deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);

        try {
            Device device = IOSServiceUtils.getDeviceManagementService().getDevice(deviceIdentifier, false);

            if (device == null || device.getDeviceIdentifier() == null || device.getDeviceIdentifier().isEmpty()) {
                msg = "Device not found for requested device id";
                throw new NotFoundException(
                        new ErrorResponse.ErrorResponseBuilder().setCode(404l).setMessage(msg).build());
            }
        } catch (DeviceManagementException e) {
            msg = "Issue in retrieving device management service instance";
            throw new UnexpectedServerErrorException(
                    new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
        }
        return deviceIdentifier;
    }

    public DeviceIDHolder validateDeviceIdentifiers(List<String> deviceIDs,
                                                    Message message, MediaType responseMediaType) {

        if (deviceIDs == null) {
            String errorMessage = "Device identifier list is empty";
            throw new BadRequestException(
                    new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
        }

        List<String> errorDeviceIdList = new ArrayList<String>();
        List<DeviceIdentifier> validDeviceIDList = new ArrayList<DeviceIdentifier>();

        int deviceIDCounter = 0;
        for (String deviceID : deviceIDs) {

            deviceIDCounter++;

            if (deviceID == null || deviceID.isEmpty()) {
                errorDeviceIdList.add(String.format(DEVICE_ID_NOT_FOUND, deviceIDCounter));
                continue;
            }

            try {
                DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
                deviceIdentifier.setId(deviceID);
                deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);

                Device device = IOSServiceUtils.getDeviceManagementService().getDevice(deviceIdentifier, false);

                if (device == null || device.getDeviceIdentifier() == null || device.getDeviceIdentifier().isEmpty()) {
                    errorDeviceIdList.add(String.format(DEVICE_ID_NOT_FOUND, deviceIDCounter));
                }

                validDeviceIDList.add(deviceIdentifier);
            } catch (DeviceManagementException e) {
                errorDeviceIdList.add(String.format(DEVICE_ID_SERVICE_NOT_FOUND, deviceIDCounter));
            }
        }

        DeviceIDHolder deviceIDHolder = new DeviceIDHolder();
        deviceIDHolder.setValidDeviceIDList(validDeviceIDList);
        deviceIDHolder.setErrorDeviceIdList(errorDeviceIdList);

        return deviceIDHolder;
    }

    public String convertErrorMapIntoErrorMessage(List<String> errorDeviceIdList) {
        return StringUtils.join(errorDeviceIdList.iterator(), COMMA_SEPARATION_PATTERN);
    }

}
