package id.iptek.utms.agent.queue;

import com.google.gson.Gson;
import id.iptek.utms.agent.dao.ProfileDao;
import id.iptek.utms.agent.model.Profile;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author jakar
 */
public class DeviceInitQueueMessageHandler implements QueueMessageHandler<Map> {

    public final static String NAME = "DEV_INIT_QUEUE_HANDLER";
    private Logger logger = LoggerFactory.getLogger(getClass());
    private ProfileDao profileDao = new ProfileDao();
    private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");

    public DeviceInitQueueMessageHandler() {
    }

    @Override
    public boolean handleMessage(Map message) {
        boolean processed = false;
        try {
            logger.debug("Handling init request: {}", message);
            long start = System.currentTimeMillis();
            
            MqttClient mqttClient = (MqttClient) message.get("MQTT");
            String terminalSN = (String) message.get("device_sn");
            Profile profile = profileDao.getProfileForTerminal(terminalSN);
            if (profile != null) {
                broadcastProfile(mqttClient, profile);
            } else {
                logger.warn("No profile for SN: {}", terminalSN);
            }
            processed = true;
            long end = System.currentTimeMillis();
            logger.debug("Saved in {}ms", (end-start));
            return processed;
        } catch(Exception ex) {
            logger.error("Error handling init: {}", ex.getMessage(), ex);
            return false;
        }
    }

    @Override
    public boolean handleMessages(List<Map> messages) {
        try {
            logger.debug("Handling list of init requests: {}", messages.size());
            long start = System.currentTimeMillis();
            boolean processed = false;
            for(Map message : messages) {
                MqttClient mqttClient = (MqttClient) message.get("MQTT");
                String terminalSN = (String) message.get("device_sn");
                Profile profile = profileDao.getProfileForTerminal(terminalSN);
                if (profile != null) {
                    broadcastProfile(mqttClient, profile);
                } else {
                    logger.warn("No profile for SN: {}", terminalSN);
                }
                processed |= true;
            }
            long end = System.currentTimeMillis();
            logger.debug("Saved in {}ms", (end-start));
            return processed;
        } catch(Exception ex) {
            logger.error("Error handling list of init requests: {}", ex.getMessage(), ex);
            return false;
        }
    }

    // send profile to device topic via mqtt
    public void broadcastProfile(MqttClient mqttClient,
            Profile profile) throws Exception {
        logger.debug("Publish profile ...");
        try {
            try {
                Gson gson = new Gson();
                int qos = 2;
                String topicName = profile.getTerminalSN().toUpperCase() + "_IN";
                // generate json
                Map messageMap = new HashMap<>();
                messageMap.put("req_id", UUID.randomUUID().toString());
                messageMap.put("req_time", dateTimeFormat.format(new Date()));
                messageMap.put("req_type", "UPDATE_PARAM");
                // profile map
                Map profileMap = new HashMap<>();
                profileMap.put("id", profile.getId());
                profileMap.put("name", profile.getName());
                profileMap.put("hearbeat_interval", profile.getHeartbeatInterval());
                profileMap.put("diagnostic_interval", profile.getDiagnosticInterval());
                profileMap.put("mask_home_button", profile.isMaskHomeButton());
                profileMap.put("mask_status_button", profile.isMaskStatusButton());
                profileMap.put("schedule_reboot", profile.isScheduleReboot());
                if (profile.isScheduleReboot()) {
                    profileMap.put("schedule_reboot_time", timeFormat.format(profile.getScheduleRebootTime()));
                }
                profileMap.put("relocation_alert", profile.isRelocationAlert());
                profileMap.put("moving_threshold", profile.getMovingThreshold());
                profileMap.put("admin_password", profile.getAdminPassword());
                
                // additional
                profileMap.put("front_app", profile.getFrontApp());
                profileMap.put("apps_home_list", profile.getApps());
                profileMap.put("group_list", profile.getGroupIds());
                                
                messageMap.put("profile", profileMap);

                String messageData = gson.toJson(messageMap);

                logger.debug("Try publish message to: {}", topicName);
                mqttClient.publish(topicName, messageData.getBytes(), qos, false);
                logger.debug("Message published!");
            } catch (Exception ex) {
                logger.error("Error publish to device: {}", ex.getMessage(), ex);
            } finally {
            }
        } finally {
            logger.debug("Publish profile DONE");
        }
    }
    
}
