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

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.notnoop.apns.APNS;
import com.notnoop.apns.ApnsService;
import org.wso2.carbon.device.mgt.ios.apns.dto.SilentPushPayload;
import org.wso2.carbon.device.mgt.ios.apns.exception.APNSException;

import java.io.InputStream;

public class PushNotificationSender {

    private static final int CONTENT_AVAILABLE = 1;
	ApnsService service = null;

	public PushNotificationSender(InputStream inputStream, String certPassword, boolean isProductionMode) {

		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 token, String title, String message) throws APNSException {

        if (token == null) {
            throw new APNSException("Device Token cannot be null");
        }

		//String payload = APNS.newPayload().alertBody(message).build();
		String payload = this.generateAPSPayload(title, message);
        service.push(token, payload);
	}

    public void silentPushToAPNS(String token, String operationCode, int operationId) throws APNSException {

        try {
            this.service.push(token, generateSilentPushPayload(operationCode, operationId));
        } catch (JsonProcessingException e) {
            throw new APNSException("Error occurred when generating silent push payload", e);
        }

    }

    private String generateSilentPushPayload(String operationCode, int operationId) throws JsonProcessingException {

        SilentPushPayload silentPushPayload = new SilentPushPayload();

        SilentPushPayload.ContentAvailable contentAvailable = silentPushPayload.new ContentAvailable();
        contentAvailable.setContentAvailable(CONTENT_AVAILABLE);

        SilentPushPayload.Extra extra = silentPushPayload.new Extra();
        extra.setOperation(operationCode);
        extra.setOperationId(Integer.toString(operationId));

        silentPushPayload.setAps(contentAvailable);
        silentPushPayload.setExtra(extra);
        Gson gson = new Gson();
        return gson.toJson(silentPushPayload);
    }

    private String generateAPSPayload(String title, String message) {
        if (message != null && !message.isEmpty()) {
            JsonObject pload = new JsonObject();
            JsonObject aps = new JsonObject();
            JsonObject alert = new JsonObject();

            if (title != null && !title.isEmpty()) {
                alert.addProperty("title", title);
            }
            alert.addProperty("body", message);
            aps.add("alert", alert);
            aps.addProperty("sound", "default");
            pload.add("aps", aps);
            return pload.toString();
        }
        return null;
    }


//        {
//            "aps" : {
//                "alert" : {
//                    "title" : "Milan",
//                    "body" : "hahaha"
//                },
//                "sound" : "default"
//                }
//            }
//        }

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

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