package org.wso2.carbon.device.mgt.ios.apns.service.impl;

import com.notnoop.apns.APNS;
import com.notnoop.apns.ApnsService;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.ios.apns.exception.APNSException;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;

public class MDMPushNotificationSender {

    private static final Log log = LogFactory.getLog(MDMPushNotificationSender.class);
    public static final String UTF_8 = "UTF-8";
    public static final String BYTE_FORMAT_STRING = "%02x";

	ApnsService service = null;

	public MDMPushNotificationSender(InputStream inputStream, String certPassword, boolean isProductionMode)
            throws APNSException {

		if (isProductionMode) {
			service = APNS.newService().withCert(inputStream, certPassword).withProductionDestination().build();
		} else {
			service = APNS.newService().withCert(inputStream, certPassword).withSandboxDestination().build();
		}

		service.start();
	}

	public void pushToAPNS(String deviceToken, String magicToken) throws APNSException {

        try {
            String mdmPayload = APNS.newPayload().mdm(magicToken).build();
            byte[] decodedBytes = Base64.decodeBase64(deviceToken.getBytes(UTF_8));
            StringBuffer byteBuffer = new StringBuffer();

            for (int i = 0; i < decodedBytes.length; ++i) {
                byteBuffer.append(String.format(BYTE_FORMAT_STRING, decodedBytes[i]));
            }

            String hexDeviceToken = byteBuffer.toString();
            service.push(hexDeviceToken, mdmPayload);
        } catch (UnsupportedEncodingException e) {
            String errorMsg = "Unsupported encoding when sending MDM push notification message";
            log.error(errorMsg, e);
            throw new APNSException(errorMsg, e);
        } finally {
            if (service != null) {
                service.stop();
            }
        }
    }

    public void stopService() {
        service.stop();
    }

    public void testConnection() {
        service.testConnection();
    }
}
