/*
 * Copyright (C) 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.googlecode.android_scripting.facade;

import com.google.android.mms.ContentType;
import com.google.android.mms.InvalidHeaderValueException;
import com.google.android.mms.pdu.CharacterSets;
import com.google.android.mms.pdu.EncodedStringValue;
import com.google.android.mms.pdu.GenericPdu;
import com.google.android.mms.pdu.PduBody;
import com.google.android.mms.pdu.PduComposer;
import com.google.android.mms.pdu.PduHeaders;
import com.google.android.mms.pdu.PduParser;
import com.google.android.mms.pdu.PduPart;
import com.google.android.mms.pdu.PduPersister;
import com.google.android.mms.pdu.SendConf;
import com.google.android.mms.pdu.SendReq;
import com.google.android.mms.MmsException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Telephony.Sms.Intents;
import android.provider.Telephony.Mms;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.telephony.SmsCbMessage;
import com.android.internal.telephony.gsm.SmsCbConstants;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import android.telephony.SmsCbEtwsInfo;
import android.telephony.SmsCbCmasInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;

import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcDefault;
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;
import com.googlecode.android_scripting.facade.telephony.TelephonyConstants;

//FIXME: Change the build order to use constants defined in here
//import com.googlecode.android_scripting.provider.TelephonyTestProvider;

/**
 * Exposes SmsManager functionality.
 */
public class SmsFacade extends RpcReceiver {

    static final boolean DBG = false;

    private final EventFacade mEventFacade;
    private final SmsManager mSms;
    private final Context mContext;
    private final Service mService;
    private BroadcastReceiver mSmsSendListener;
    private BroadcastReceiver mSmsIncomingListener;
    private int mNumExpectedSentEvents;
    private int mNumExpectedDeliveredEvents;
    private boolean mListeningIncomingSms;
    private IntentFilter mEmergencyCBMessage;
    private BroadcastReceiver mGsmEmergencyCBMessageListener;
    private BroadcastReceiver mCdmaEmergencyCBMessageListener;
    private boolean mGsmEmergencyCBListenerRegistered;
    private boolean mCdmaEmergencyCBListenerRegistered;
    private boolean mSentReceiversRegistered;
    private Object lock = new Object();

    private BroadcastReceiver mMmsSendListener;
    private BroadcastReceiver mMmsIncomingListener;
    private boolean mListeningIncomingMms;

    TelephonyManager mTelephonyManager;

    private static final String SMS_MESSAGE_STATUS_DELIVERED_ACTION =
            "com.googlecode.android_scripting.sms.MESSAGE_STATUS_DELIVERED";
    private static final String SMS_MESSAGE_SENT_ACTION =
            "com.googlecode.android_scripting.sms.MESSAGE_SENT";

    private static final String EMERGENCY_CB_MESSAGE_RECEIVED_ACTION =
            "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";

    private static final String MMS_MESSAGE_SENT_ACTION =
            "com.googlecode.android_scripting.mms.MESSAGE_SENT";

    private final int MAX_MESSAGE_LENGTH = 160;
    private final int INTERNATIONAL_NUMBER_LENGTH = 12;
    private final int DOMESTIC_NUMBER_LENGTH = 10;

    private static final String DEFAULT_FROM_PHONE_NUMBER = new String("8675309");

    private final int[] mGsmCbMessageIdList = {
            SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING,
            SmsCbConstants.MESSAGE_ID_ETWS_TSUNAMI_WARNING,
            SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING,
            SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE,
            SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST,
            SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE
    };

    private final int[] mCdmaCbMessageIdList = {
            SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
            SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
            SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
            SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
            SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE
    };

    public SmsFacade(FacadeManager manager) {

        super(manager);
        mService = manager.getService();
        mContext = mService;
        mSms = SmsManager.getDefault();
        mEventFacade = manager.getReceiver(EventFacade.class);
        mSmsSendListener = new SmsSendListener();
        mSmsIncomingListener = new SmsIncomingListener();
        mNumExpectedSentEvents = 0;
        mNumExpectedDeliveredEvents = 0;
        mListeningIncomingSms = false;
        mGsmEmergencyCBMessageListener = new SmsEmergencyCBMessageListener();
        mCdmaEmergencyCBMessageListener = new SmsEmergencyCBMessageListener();
        mGsmEmergencyCBListenerRegistered = false;
        mCdmaEmergencyCBListenerRegistered = false;
        mSentReceiversRegistered = false;

        mMmsIncomingListener = new MmsIncomingListener();
        mMmsSendListener = new MmsSendListener();

        mListeningIncomingMms = false;

        IntentFilter smsFilter = new IntentFilter(SMS_MESSAGE_SENT_ACTION);
        smsFilter.addAction(SMS_MESSAGE_STATUS_DELIVERED_ACTION);

        IntentFilter mmsFilter = new IntentFilter(MMS_MESSAGE_SENT_ACTION);

        synchronized (lock) {
            mService.registerReceiver(mSmsSendListener, smsFilter);
            mService.registerReceiver(mMmsSendListener, mmsFilter);
            mSentReceiversRegistered = true;
        }

        mTelephonyManager =
                (TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE);
    }

    // FIXME: Move to a utility class
    // FIXME: remove the MODE_WORLD_READABLE once we verify the use case
    @SuppressWarnings("deprecation")
    private boolean writeBytesToFile(String fileName, byte[] pdu) {
        FileOutputStream writer = null;
        try {
            writer = mContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
            writer.write(pdu);
            return true;
        } catch (final IOException e) {
            return false;
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                }
            }
        }
    }

    // FIXME: Move to a utility class
    private boolean writeBytesToCacheFile(String fileName, byte[] pdu) {
        File mmsFile = new File(mContext.getCacheDir(), fileName);
        Log.d(String.format("filename:%s, directory:%s", fileName,
                mContext.getCacheDir().toString()));
        FileOutputStream writer = null;
        try {
            writer = new FileOutputStream(mmsFile);
            writer.write(pdu);
            return true;
        } catch (final IOException e) {
            Log.d("writeBytesToCacheFile() failed with " + e.toString());
            return false;
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                }
            }
        }
    }

    @Deprecated
    @Rpc(description = "Starts tracking incoming SMS.")
    public void smsStartTrackingIncomingMessage() {
        Log.d("Using Deprecated smsStartTrackingIncomingMessage!");
        smsStartTrackingIncomingSmsMessage();
    }

    @Rpc(description = "Starts tracking incoming SMS.")
    public void smsStartTrackingIncomingSmsMessage() {
        mService.registerReceiver(mSmsIncomingListener,
                new IntentFilter(Intents.SMS_RECEIVED_ACTION));
        mListeningIncomingSms = true;
    }

    @Deprecated
    @Rpc(description = "Stops tracking incoming SMS.")
    public void smsStopTrackingIncomingMessage() {
        Log.d("Using Deprecated smsStopTrackingIncomingMessage!");
        smsStopTrackingIncomingSmsMessage();
    }

    @Rpc(description = "Stops tracking incoming SMS.")
    public void smsStopTrackingIncomingSmsMessage() {
        if (mListeningIncomingSms) {
            mListeningIncomingSms = false;
            try {
                mService.unregisterReceiver(mSmsIncomingListener);
            } catch (Exception e) {
                Log.e("Tried to unregister nonexistent SMS Listener!");
            }
        }
    }

    @Rpc(description = "Starts tracking incoming MMS.")
    public void smsStartTrackingIncomingMmsMessage() {
        IntentFilter mmsReceived = new IntentFilter(Intents.MMS_DOWNLOADED_ACTION);
        mmsReceived.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
        mmsReceived.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
        mService.registerReceiver(mMmsIncomingListener, mmsReceived);
        mListeningIncomingSms = true;
    }

    @Rpc(description = "Stops tracking incoming MMS.")
    public void smsStopTrackingIncomingMmsMessage() {
        if (mListeningIncomingMms) {
            mListeningIncomingMms = false;
            try {
                mService.unregisterReceiver(mMmsIncomingListener);
            } catch (Exception e) {
                Log.e("Tried to unregister nonexistent MMS Listener!");
            }
        }
    }

    // Currently requires 'adb shell su root setenforce 0'
    @Rpc(description = "Send a multimedia message to a specified number.")
    public void smsSendMultimediaMessage(
                        @RpcParameter(name = "toPhoneNumber")
            String toPhoneNumber,
                        @RpcParameter(name = "subject")
            String subject,
                        @RpcParameter(name = "message")
            String message,
            @RpcParameter(name = "fromPhoneNumber")
            @RpcOptional
            String fromPhoneNumber,
            @RpcParameter(name = "fileName")
            @RpcOptional
            String fileName) {

        MmsBuilder mms = new MmsBuilder();

        mms.setToPhoneNumber(toPhoneNumber);
        if (fromPhoneNumber == null) {
            mTelephonyManager.getLine1Number(); //TODO: b/21592513 - multi-sim awareness
        }

        if (DBG) {
            Log.d(String.format(
                    "Params:toPhoneNumber(%s),subject(%s),message(%s),fromPhoneNumber(%s),filename(%s)",
                    toPhoneNumber, subject, message,
                    (fromPhoneNumber != null) ? fromPhoneNumber : "",
                            (fileName != null) ? fileName : ""));
        }

        mms.setFromPhoneNumber((fromPhoneNumber != null) ? fromPhoneNumber : DEFAULT_FROM_PHONE_NUMBER);
        mms.setSubject(subject);
        mms.setDate();
        mms.addMessageBody(message);
        mms.setMessageClass(MmsBuilder.MESSAGE_CLASS_PERSONAL);
        mms.setMessagePriority(MmsBuilder.DEFAULT_PRIORITY);
        mms.setDeliveryReport(true);
        mms.setReadReport(true);
        // Default to 1 week;
        mms.setExpirySeconds(MmsBuilder.DEFAULT_EXPIRY_TIME);

        Uri contentUri = null;

        String randomFileName = "mms." + String.valueOf(System.currentTimeMillis()) + ".dat";

        byte[] mmsBytes = mms.build();
        if (mmsBytes.length == 0) {
            Log.e("Failed to build PDU!");
            return;
        }

        if (writeBytesToCacheFile(randomFileName, mmsBytes) == false) {
            Log.e("Failed to write PDU to file");
            return;
        }

        contentUri = (new Uri.Builder())
                .authority("com.googlecode.android_scripting.provider.telephonytestprovider")
                .path("mms/" + randomFileName)
                .scheme(ContentResolver.SCHEME_CONTENT)
                .build();

        if (contentUri != null) {
            Log.d(String.format("URI String: %s", contentUri.toString()));

            SmsManager.getDefault().sendMultimediaMessage(mContext,
                    contentUri, null/* locationUrl */, null/* configOverrides */,
                    PendingIntent.getBroadcast(mService, 0,
                            new Intent(MMS_MESSAGE_SENT_ACTION), 0)
                    );
        }
        else {
            Log.d("smsSendMultimediaMessage():Content URI String is null");
        }
    }

    @Rpc(description = "Send a text message to a specified number.")
    public void smsSendTextMessage(
                        @RpcParameter(name = "phoneNumber")
            String phoneNumber,
                        @RpcParameter(name = "message")
            String message,
                        @RpcParameter(name = "deliveryReportRequired")
            Boolean deliveryReportRequired) {

        if (message.length() > MAX_MESSAGE_LENGTH) {
            ArrayList<String> messagesParts = mSms.divideMessage(message);
            mNumExpectedSentEvents = mNumExpectedDeliveredEvents = messagesParts.size();
            ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
            ArrayList<PendingIntent> deliveredIntents = new ArrayList<PendingIntent>();
            for (int i = 0; i < messagesParts.size(); i++) {
                sentIntents.add(PendingIntent.getBroadcast(mService, 0,
                        new Intent(SMS_MESSAGE_SENT_ACTION), 0));
                if (deliveryReportRequired) {
                    deliveredIntents.add(
                            PendingIntent.getBroadcast(mService, 0,
                                    new Intent(SMS_MESSAGE_STATUS_DELIVERED_ACTION), 0));
                }
            }
            mSms.sendMultipartTextMessage(
                    phoneNumber, null, messagesParts,
                    sentIntents, deliveryReportRequired ? deliveredIntents : null);
        } else {
            mNumExpectedSentEvents = mNumExpectedDeliveredEvents = 1;
            PendingIntent sentIntent = PendingIntent.getBroadcast(mService, 0,
                    new Intent(SMS_MESSAGE_SENT_ACTION), 0);
            PendingIntent deliveredIntent = PendingIntent.getBroadcast(mService, 0,
                    new Intent(SMS_MESSAGE_STATUS_DELIVERED_ACTION), 0);
            mSms.sendTextMessage(
                    phoneNumber, null, message, sentIntent,
                    deliveryReportRequired ? deliveredIntent : null);
        }
    }

    @Rpc(description = "Retrieves all messages currently stored on ICC.")
    public ArrayList<SmsMessage> smsGetAllMessagesFromIcc() {
        return SmsManager.getDefault().getAllMessagesFromIcc();
    }

    @Rpc(description = "Starts tracking GSM Emergency CB Messages.")
    public void smsStartTrackingGsmEmergencyCBMessage() {
        if (!mGsmEmergencyCBListenerRegistered) {
            for (int messageId : mGsmCbMessageIdList) {
                mSms.enableCellBroadcast(
                        messageId,
                        SmsManager.CELL_BROADCAST_RAN_TYPE_GSM);
            }

            mEmergencyCBMessage = new IntentFilter(EMERGENCY_CB_MESSAGE_RECEIVED_ACTION);
            mService.registerReceiver(mGsmEmergencyCBMessageListener,
                    mEmergencyCBMessage);
            mGsmEmergencyCBListenerRegistered = true;
        }
    }

    @Rpc(description = "Stop tracking GSM Emergency CB Messages")
    public void smsStopTrackingGsmEmergencyCBMessage() {
        if (mGsmEmergencyCBListenerRegistered) {
            mService.unregisterReceiver(mGsmEmergencyCBMessageListener);
            mGsmEmergencyCBListenerRegistered = false;
            for (int messageId : mGsmCbMessageIdList) {
                mSms.disableCellBroadcast(
                        messageId,
                        SmsManager.CELL_BROADCAST_RAN_TYPE_GSM);
            }
        }
    }

    @Rpc(description = "Starts tracking CDMA Emergency CB Messages")
    public void smsStartTrackingCdmaEmergencyCBMessage() {
        if (!mCdmaEmergencyCBListenerRegistered) {
            for (int messageId : mCdmaCbMessageIdList) {
                mSms.enableCellBroadcast(
                        messageId,
                        SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA);
            }
            mEmergencyCBMessage = new IntentFilter(EMERGENCY_CB_MESSAGE_RECEIVED_ACTION);
            mService.registerReceiver(mCdmaEmergencyCBMessageListener,
                    mEmergencyCBMessage);
            mCdmaEmergencyCBListenerRegistered = true;
        }
    }

    @Rpc(description = "Stop tracking CDMA Emergency CB Message.")
    public void smsStopTrackingCdmaEmergencyCBMessage() {
        if (mCdmaEmergencyCBListenerRegistered) {
            mService.unregisterReceiver(mCdmaEmergencyCBMessageListener);
            mCdmaEmergencyCBListenerRegistered = false;
            for (int messageId : mCdmaCbMessageIdList) {
                mSms.disableCellBroadcast(
                        messageId,
                        SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA);
            }
        }
    }

    private class SmsSendListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle event = new Bundle();
            event.putString("Type", "SmsDeliverStatus");
            String action = intent.getAction();
            int resultCode = getResultCode();
            if (SMS_MESSAGE_STATUS_DELIVERED_ACTION.equals(action)) {
                if (resultCode == Activity.RESULT_OK) {
                    if (mNumExpectedDeliveredEvents == 1) {
                        Log.d("SMS Message delivered successfully");
                        mEventFacade.postEvent(TelephonyConstants.EventSmsDeliverSuccess, event);
                    }
                    if (mNumExpectedDeliveredEvents > 0) {
                        mNumExpectedDeliveredEvents--;
                    }
                } else {
                    Log.e("SMS Message delivery failed");
                    // TODO . Need to find the reason for failure from pdu
                    mEventFacade.postEvent(TelephonyConstants.EventSmsDeliverFailure, event);
                }
            } else if (SMS_MESSAGE_SENT_ACTION.equals(action)) {
                if (resultCode == Activity.RESULT_OK) {
                    if (mNumExpectedSentEvents == 1) {
                        event.putString("Type", "SmsSentSuccess");
                        Log.d("SMS Message sent successfully");
                        mEventFacade.postEvent(TelephonyConstants.EventSmsSentSuccess, event);
                    }
                    if (mNumExpectedSentEvents > 0) {
                        mNumExpectedSentEvents--;
                    }
                } else {
                    Log.e("SMS Message send failed");
                    event.putString("Type", "SmsSentFailure");
                    switch (resultCode) {
                        case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                            event.putString("Reason", "GenericFailure");
                            break;
                        case SmsManager.RESULT_ERROR_RADIO_OFF:
                            event.putString("Reason", "RadioOff");
                            break;
                        case SmsManager.RESULT_ERROR_NULL_PDU:
                            event.putString("Reason", "NullPdu");
                            break;
                        case SmsManager.RESULT_ERROR_NO_SERVICE:
                            event.putString("Reason", "NoService");
                            break;
                        case SmsManager.RESULT_ERROR_LIMIT_EXCEEDED:
                            event.putString("Reason", "LimitExceeded");
                            break;
                        case SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE:
                            event.putString("Reason", "FdnCheckFailure");
                            break;
                        default:
                            event.putString("Reason", "Unknown");
                            break;
                    }
                    mEventFacade.postEvent(TelephonyConstants.EventSmsSentFailure, event);
                }
            }
        }
    }

    private class SmsIncomingListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (Intents.SMS_RECEIVED_ACTION.equals(action)) {
                Log.d("New SMS Received");
                Bundle extras = intent.getExtras();
                int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
                if (extras != null) {
                    Bundle event = new Bundle();
                    event.putString("Type", "NewSmsReceived");
                    SmsMessage[] msgs = Intents.getMessagesFromIntent(intent);
                    StringBuilder smsMsg = new StringBuilder();

                    SmsMessage sms = msgs[0];
                    String sender = sms.getOriginatingAddress();
                    event.putString("Sender", formatPhoneNumber(sender));

                    for (int i = 0; i < msgs.length; i++) {
                        sms = msgs[i];
                        smsMsg.append(sms.getMessageBody());
                    }
                    event.putString("Text", smsMsg.toString());
                    // TODO
                    // Need to explore how to get subId information.
                    event.putInt("subscriptionId", subId);
                    mEventFacade.postEvent(TelephonyConstants.EventSmsReceived, event);
                }
            }
        }
    }

    private class MmsSendListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle event = new Bundle();
            String action = intent.getAction();
            int resultCode = getResultCode();
            event.putString("ResultCode", Integer.toString(resultCode));
            if (MMS_MESSAGE_SENT_ACTION.equals(action)) {
                if (resultCode == Activity.RESULT_OK) {
                    Log.d("MMS Message sent successfully");
                    mEventFacade.postEvent(TelephonyConstants.EventMmsSentSuccess, event);
                } else {
                    Log.e(String.format("MMS Message send failed: %d", resultCode));
                    mEventFacade.postEvent(TelephonyConstants.EventMmsSentFailure, event);
                }
            } else {
                Log.e("MMS Send Listener Received Invalid Event" + intent.toString());
            }
        }
    }

    // b/21569494 - Never receiving ANY of these events: requires debugging
    private class MmsIncomingListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("MmsIncomingListener Received an Intent " + intent.toString());
            String action = intent.getAction();
            if (Intents.MMS_DOWNLOADED_ACTION.equals(action)) {
                Log.d("New MMS Downloaded");
                mEventFacade.postEvent(TelephonyConstants.EventMmsDownloaded, new Bundle());
            }
            else if (Intents.WAP_PUSH_RECEIVED_ACTION.equals(action)) {
                Log.d("New Wap Push Received");
                mEventFacade.postEvent(TelephonyConstants.EventWapPushReceived, new Bundle());
            }
            else if (Intents.DATA_SMS_RECEIVED_ACTION.equals(action)) {
                Log.d("New Data SMS Received");
                mEventFacade.postEvent(TelephonyConstants.EventDataSmsReceived, new Bundle());
            }
            else {
                Log.e("MmsIncomingListener Received Unexpected Event" + intent.toString());
            }
        }
    }

    String formatPhoneNumber(String phoneNumber) {
        String senderNumberStr = null;
        int len = phoneNumber.length();
        if (len > 0) {
            /**
             * Currently this incomingNumber modification is specific for US numbers.
             */
            if ((INTERNATIONAL_NUMBER_LENGTH == len) && ('+' == phoneNumber.charAt(0))) {
                senderNumberStr = phoneNumber.substring(1);
            } else if (DOMESTIC_NUMBER_LENGTH == len) {
                senderNumberStr = '1' + phoneNumber;
            } else {
                senderNumberStr = phoneNumber;
            }
        }
        return senderNumberStr;
    }

    private class SmsEmergencyCBMessageListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (EMERGENCY_CB_MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) {
                Bundle extras = intent.getExtras();
                if (extras != null) {
                    Bundle event = new Bundle();
                    String eventName = null;
                    SmsCbMessage message = (SmsCbMessage) extras.get("message");
                    if (message != null) {
                        if (message.isEmergencyMessage()) {
                            event.putString("geographicalScope", getGeographicalScope(
                                    message.getGeographicalScope()));
                            event.putInt("serialNumber", message.getSerialNumber());
                            event.putString("location", message.getLocation().toString());
                            event.putInt("serviceCategory", message.getServiceCategory());
                            event.putString("language", message.getLanguageCode());
                            event.putString("message", message.getMessageBody());
                            event.putString("priority", getPriority(message.getMessagePriority()));
                            if (message.isCmasMessage()) {
                                // CMAS message
                                eventName = TelephonyConstants.EventCmasReceived;
                                event.putString("cmasMessageClass", getCMASMessageClass(
                                        message.getCmasWarningInfo().getMessageClass()));
                                event.putString("cmasCategory", getCMASCategory(
                                        message.getCmasWarningInfo().getCategory()));
                                event.putString("cmasResponseType", getCMASResponseType(
                                        message.getCmasWarningInfo().getResponseType()));
                                event.putString("cmasSeverity", getCMASSeverity(
                                        message.getCmasWarningInfo().getSeverity()));
                                event.putString("cmasUrgency", getCMASUrgency(
                                        message.getCmasWarningInfo().getUrgency()));
                                event.putString("cmasCertainty", getCMASCertainty(
                                        message.getCmasWarningInfo().getCertainty()));
                            } else if (message.isEtwsMessage()) {
                                // ETWS message
                                eventName = TelephonyConstants.EventEtwsReceived;
                                event.putString("etwsWarningType", getETWSWarningType(
                                        message.getEtwsWarningInfo().getWarningType()));
                                event.putBoolean("etwsIsEmergencyUserAlert",
                                        message.getEtwsWarningInfo().isEmergencyUserAlert());
                                event.putBoolean("etwsActivatePopup",
                                        message.getEtwsWarningInfo().isPopupAlert());
                            } else {
                                Log.d("Received message is not CMAS or ETWS");
                            }
                            if (eventName != null)
                                mEventFacade.postEvent(eventName, event);
                        }
                    }
                } else {
                    Log.d("Received  Emergency CB without extras");
                }
            }
        }
    }

    private static String getETWSWarningType(int type) {
        switch (type) {
            case SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE:
                return "EARTHQUAKE";
            case SmsCbEtwsInfo.ETWS_WARNING_TYPE_TSUNAMI:
                return "TSUNAMI";
            case SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI:
                return "EARTHQUAKE_AND_TSUNAMI";
            case SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE:
                return "TEST_MESSAGE";
            case SmsCbEtwsInfo.ETWS_WARNING_TYPE_OTHER_EMERGENCY:
                return "OTHER_EMERGENCY";
        }
        return "UNKNOWN";
    }

    private static String getCMASMessageClass(int messageclass) {
        switch (messageclass) {
            case SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT:
                return "PRESIDENTIAL_LEVEL_ALERT";
            case SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT:
                return "EXTREME_THREAT";
            case SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT:
                return "SEVERE_THREAT";
            case SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY:
                return "CHILD_ABDUCTION_EMERGENCY";
            case SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST:
                return "REQUIRED_MONTHLY_TEST";
            case SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE:
                return "CMAS_EXERCISE";
        }
        return "UNKNOWN";
    }

    private static String getCMASCategory(int category) {
        switch (category) {
            case SmsCbCmasInfo.CMAS_CATEGORY_GEO:
                return "GEOPHYSICAL";
            case SmsCbCmasInfo.CMAS_CATEGORY_MET:
                return "METEOROLOGICAL";
            case SmsCbCmasInfo.CMAS_CATEGORY_SAFETY:
                return "SAFETY";
            case SmsCbCmasInfo.CMAS_CATEGORY_SECURITY:
                return "SECURITY";
            case SmsCbCmasInfo.CMAS_CATEGORY_RESCUE:
                return "RESCUE";
            case SmsCbCmasInfo.CMAS_CATEGORY_FIRE:
                return "FIRE";
            case SmsCbCmasInfo.CMAS_CATEGORY_HEALTH:
                return "HEALTH";
            case SmsCbCmasInfo.CMAS_CATEGORY_ENV:
                return "ENVIRONMENTAL";
            case SmsCbCmasInfo.CMAS_CATEGORY_TRANSPORT:
                return "TRANSPORTATION";
            case SmsCbCmasInfo.CMAS_CATEGORY_INFRA:
                return "INFRASTRUCTURE";
            case SmsCbCmasInfo.CMAS_CATEGORY_CBRNE:
                return "CHEMICAL";
            case SmsCbCmasInfo.CMAS_CATEGORY_OTHER:
                return "OTHER";
        }
        return "UNKNOWN";
    }

    private static String getCMASResponseType(int type) {
        switch (type) {
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_SHELTER:
                return "SHELTER";
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_EVACUATE:
                return "EVACUATE";
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_PREPARE:
                return "PREPARE";
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_EXECUTE:
                return "EXECUTE";
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR:
                return "MONITOR";
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_AVOID:
                return "AVOID";
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_ASSESS:
                return "ASSESS";
            case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE:
                return "NONE";
        }
        return "UNKNOWN";
    }

    private static String getCMASSeverity(int severity) {
        switch (severity) {
            case SmsCbCmasInfo.CMAS_SEVERITY_EXTREME:
                return "EXTREME";
            case SmsCbCmasInfo.CMAS_SEVERITY_SEVERE:
                return "SEVERE";
        }
        return "UNKNOWN";
    }

    private static String getCMASUrgency(int urgency) {
        switch (urgency) {
            case SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE:
                return "IMMEDIATE";
            case SmsCbCmasInfo.CMAS_URGENCY_EXPECTED:
                return "EXPECTED";
        }
        return "UNKNOWN";
    }

    private static String getCMASCertainty(int certainty) {
        switch (certainty) {
            case SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED:
                return "IMMEDIATE";
            case SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY:
                return "LIKELY";
        }
        return "UNKNOWN";
    }

    private static String getGeographicalScope(int scope) {
        switch (scope) {
            case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE:
                return "CELL_WIDE_IMMEDIATE";
            case SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE:
                return "PLMN_WIDE ";
            case SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE:
                return "LA_WIDE";
            case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE:
                return "CELL_WIDE";
        }
        return "UNKNOWN";
    }

    private static String getPriority(int priority) {
        switch (priority) {
            case SmsCbMessage.MESSAGE_PRIORITY_NORMAL:
                return "NORMAL";
            case SmsCbMessage.MESSAGE_PRIORITY_INTERACTIVE:
                return "INTERACTIVE";
            case SmsCbMessage.MESSAGE_PRIORITY_URGENT:
                return "URGENT";
            case SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY:
                return "EMERGENCY";
        }
        return "UNKNOWN";
    }

    @Override
    public void shutdown() {

        smsStopTrackingIncomingSmsMessage();
        smsStopTrackingIncomingMmsMessage();
        smsStopTrackingGsmEmergencyCBMessage();
        smsStopTrackingCdmaEmergencyCBMessage();

        synchronized (lock) {
            if (mSentReceiversRegistered) {
                mService.unregisterReceiver(mSmsSendListener);
                mService.unregisterReceiver(mMmsSendListener);
                mSentReceiversRegistered = false;
            }
        }
    }

    private class MmsBuilder {

        public static final String MESSAGE_CLASS_PERSONAL =
                PduHeaders.MESSAGE_CLASS_PERSONAL_STR;

        public static final String MESSAGE_CLASS_ADVERTISEMENT =
                PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR;

        public static final String MESSAGE_CLASS_INFORMATIONAL =
                PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR;

        public static final String MESSAGE_CLASS_AUTO =
                PduHeaders.MESSAGE_CLASS_AUTO_STR;

        public static final int MESSAGE_PRIORITY_LOW = PduHeaders.PRIORITY_LOW;
        public static final int MESSAGE_PRIORITY_NORMAL = PduHeaders.PRIORITY_LOW;
        public static final int MESSAGE_PRIORITY_HIGH = PduHeaders.PRIORITY_LOW;

        private static final int DEFAULT_EXPIRY_TIME = 7 * 24 * 60 * 60;
        private static final int DEFAULT_PRIORITY = PduHeaders.PRIORITY_NORMAL;

        private SendReq mRequest;
        private PduBody mBody;

        // FIXME: Eventually this should be exposed as a parameter
        private static final String TEMP_CONTENT_FILE_NAME = "text0.txt";

        // Synchronized Multimedia Internet Language
        // Fragment for compatibility
        private static final String sSmilText =
                "<smil>" +
                        "<head>" +
                        "<layout>" +
                        "<root-layout/>" +
                        "<region height=\"100%%\" id=\"Text\" left=\"0%%\"" +
                        " top=\"0%%\" width=\"100%%\"/>" +
                        "</layout>" +
                        "</head>" +
                        "<body>" +
                        "<par dur=\"8000ms\">" +
                        "<text src=\"%s\" region=\"Text\"/>" +
                        "</par>" +
                        "</body>" +
                        "</smil>";

        public MmsBuilder() {
            mRequest = new SendReq();
            mBody = new PduBody();
        }

        public void setFromPhoneNumber(String number) {
            mRequest.setFrom(new EncodedStringValue(number));
        }

        public void setToPhoneNumber(String number) {
            mRequest.setTo(new EncodedStringValue[] {
                    new EncodedStringValue(number) });
        }

        public void setToPhoneNumbers(List<String> number) {
            mRequest.setTo(EncodedStringValue.encodeStrings((String[]) number.toArray()));
        }

        public void setSubject(String subject) {
            mRequest.setSubject(new EncodedStringValue(subject));
        }

        public void setDate() {
            setDate(System.currentTimeMillis() / 1000);
        }

        public void setDate(long time) {
            mRequest.setDate(time);
        }

        public void addMessageBody(String message) {
            addMessageBody(message, true);
        }

        public void setMessageClass(String messageClass) {
            mRequest.setMessageClass(messageClass.getBytes());
        }

        public void setMessagePriority(int priority) {
            try {
                mRequest.setPriority(priority);
            } catch (InvalidHeaderValueException e) {
                Log.e("Invalid Header Value "+e.toString());
            }
        }

        public void setDeliveryReport(boolean report) {
            try {
                mRequest.setDeliveryReport((report) ? PduHeaders.VALUE_YES : PduHeaders.VALUE_NO);
            } catch (InvalidHeaderValueException e) {
                Log.e("Invalid Header Value "+e.toString());
            }
        }

        public void setReadReport(boolean report) {
            try {
                mRequest.setReadReport((report) ? PduHeaders.VALUE_YES : PduHeaders.VALUE_NO);
            } catch (InvalidHeaderValueException e) {
                Log.e("Invalid Header Value "+e.toString());
            }
        }

        public void setExpirySeconds(int seconds) {
            mRequest.setExpiry(seconds);
        }

        public byte[] build() {
            mRequest.setBody(mBody);

            int msgSize = 0;
            for (int i = 0; i < mBody.getPartsNum(); i++) {
                msgSize += mBody.getPart(i).getDataLength();
            }
            mRequest.setMessageSize(msgSize);

            return new PduComposer(mContext, mRequest).make();
        }

        public void addMessageBody(String message, boolean addSmilFragment) {
            final PduPart part = new PduPart();
            part.setCharset(CharacterSets.UTF_8);
            part.setContentType(ContentType.TEXT_PLAIN.getBytes());
            part.setContentLocation("text0".getBytes());
            int index = TEMP_CONTENT_FILE_NAME.lastIndexOf(".");
            String contentId = (index == -1) ? TEMP_CONTENT_FILE_NAME
                    : TEMP_CONTENT_FILE_NAME.substring(0, index);
            part.setContentId(contentId.getBytes());
            part.setContentId("txt".getBytes());
            part.setData(message.getBytes());
            mBody.addPart(part);
            if (addSmilFragment) {
                addSmilTextFragment(TEMP_CONTENT_FILE_NAME);
            }
        }

        private void addSmilTextFragment(String contentFilename) {

            final String smil = String.format(sSmilText, contentFilename);
            final PduPart smilPart = new PduPart();
            smilPart.setContentId("smil".getBytes());
            smilPart.setContentLocation("smil.xml".getBytes());
            smilPart.setContentType(ContentType.APP_SMIL.getBytes());
            smilPart.setData(smil.getBytes());
            mBody.addPart(0, smilPart);
        }
    }

}
