package com.ericsson.uecontrol.core.behaviour;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.SmsManager;

import com.ericsson.uecontrol.core.UeBehaviour;
import com.ericsson.uecontrol.gui.MainActivity;
import com.ericsson.uecontrol.core.util.Configurator.Configurable;

import org.apache.log4j.Logger;

/**
 * Created by ezivkoc on 2014-08-06.
 */
public class UeBehaviourSendSMS extends UeBehaviour{
    private static final Logger log = Logger.getLogger(UeBehaviourSendSMS.class);
    private static final String INTENT_ACTION_SENT = "SMS_SENT";
    private static final String INTENT_ACTION_DELIVERED = "SMS_DELIVERED";
    private static final int SLEEP_PERIOD = 300;

    private static enum MessageStatus{
        UNKNOWN, MESSAGE_SENT, MESSAGE_DELIVERED, MESSAGE_SEND_ERROR, MESSAGE_CANCELED
    }

    @Configurable("Phone Number")
    private String phoneNumber;
    @Configurable("Message Text")
    private String message;

    private transient MessageStatus status;
    private transient Exception exception;


    @Override
    protected void execute() throws Exception {
        Context context = MainActivity.getContext();
        status = MessageStatus.UNKNOWN;
        exception = null;

        // Register PendingIntents and BroadcastReceivers
        log.debug("Registering PendingIntents");
        PendingIntent sentPI = PendingIntent.getBroadcast(
                context, 0, new Intent(INTENT_ACTION_SENT), 0);
        PendingIntent deliveredPI = PendingIntent.getBroadcast(
                context, 0, new Intent(INTENT_ACTION_DELIVERED), 0);

        BroadcastReceiver sentBroadcastReceiver = new BroadcastReceiver() {
            public void onReceive(Context arg0, Intent arg1) {
                setSendingStatus(getResultCode());
            }
        };
        BroadcastReceiver deliveryBroadcastReceiver = new BroadcastReceiver() {
            public void onReceive(Context arg0, Intent arg1) {
                setDeliveryStatus(getResultCode());
            }
        };
        context.registerReceiver(sentBroadcastReceiver, new IntentFilter(INTENT_ACTION_SENT));
        context.registerReceiver(deliveryBroadcastReceiver, new IntentFilter(INTENT_ACTION_DELIVERED));
        Thread.sleep(SLEEP_PERIOD);

        // Send message
        log.debug("Sending message");
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
        this.setProgress(1/3f);

        // Wait for the message sending
        log.debug("Waiting for message delivery");
        while(status != MessageStatus.MESSAGE_DELIVERED &&
                status != MessageStatus.MESSAGE_CANCELED){
            if(status == MessageStatus.MESSAGE_SENT)
                this.setProgress(2/3f);
            if(stopExecution())
                break;
            Thread.sleep(SLEEP_PERIOD);
        }
        this.setProgress(1f);

        // Cleanup
        log.debug("Cleanup");
        context.unregisterReceiver(sentBroadcastReceiver);
        context.unregisterReceiver(deliveryBroadcastReceiver);
    }

    private void setSendingStatus(int code){
        switch (code) {
            case Activity.RESULT_OK:
                log.debug("Message sent");
                status = MessageStatus.MESSAGE_SENT;
                break;
            default:
                exception = new Exception("There was an error when sending the sms: "+getCodeString(code));
        }
    }
    private void setDeliveryStatus(int code){
        switch (code) {
            case Activity.RESULT_OK:
                log.debug("Message delivered");
                status = MessageStatus.MESSAGE_DELIVERED;
                break;
            case Activity.RESULT_CANCELED:
                log.debug("Message canceled");
                status = MessageStatus.MESSAGE_CANCELED;
                break;
        }
    }
    private String getCodeString(int code){
        switch (code) {
            case Activity.RESULT_CANCELED:                  return "RESULT_CANCELED";
            case Activity.RESULT_OK:                        return "RESULT_OK";
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:   return "RESULT_ERROR_GENERIC_FAILURE";
            case SmsManager.RESULT_ERROR_NO_SERVICE:        return "RESULT_ERROR_NO_SERVICE";
            case SmsManager.RESULT_ERROR_NULL_PDU:          return "RESULT_ERROR_NULL_PDU";
            case SmsManager.RESULT_ERROR_RADIO_OFF:         return "RESULT_ERROR_RADIO_OFF";
        }
        return "UNKNOWN_CODE("+code+")";
    }


    @Override
    public String getName() {
        return "Send SMS";
    }

    @Override
    public String toString() {
        return "Will send an SMS to: " + phoneNumber;
    }
}
