/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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 android.telephony.cts;

import static android.telephony.cts.TelephonyUtils.hexStringToByteArray;

import static androidx.test.InstrumentationRegistry.getContext;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import android.content.Context;
import android.content.pm.PackageManager;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;

import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;

public class SmsMessageTest {

    private TelephonyManager mTelephonyManager;
    private PackageManager mPackageManager;

    private static final String DISPLAY_MESSAGE_BODY = "test subject /test body";
    private static final String DMB = "{ testBody[^~\\] }";
    private static final String EMAIL_ADD = "foo@example.com";
    private static final String EMAIL_FROM = "foo@example.com";
    private static final String MB = DMB;
    private static final String MESSAGE_BODY1 = "Test";
    private static final String MESSAGE_BODY2 = "(Subject)Test";
    private static final String MESSAGE_BODY3 = "\u2122\u00a9\u00aehello";
    private static final String MESSAGE_BODY4 = " ";
    private static final String MESSAGE_BODY5 = " ";
    private static final String OA = "foo@example.com";
    private static final String OA1 = "+14154255486";
    private static final String OA2 = "+15122977683";
    private static final String OA3 = "_@";
    private static final String OA4 = "\u0394@";
    // pseudo subject will always be empty
    private static final String PSEUDO_SUBJECT = "";
    private static final String SCA1 = "+16466220020";
    private static final String SCA2 = "+12063130012";
    private static final String SCA3 = "+14155551212";
    private static final String SCA4 = "+14155551212";
    private static final int NOT_CREATE_FROM_SIM = -1;
    private static final int NOT_CREATE_FROM_ICC = -1;
    private static final int PROTOCOL_IDENTIFIER = 0;
    private static final int SMS_NUMBER1 = 1;
    private static final int SMS_NUMBER2 = 1;
    private static final int SMS_NUMBER3 = 1;
    private static final int STATUS = 0;
    private static final int STATUS_ON_SIM_DEF = -1;
    private static final int STATUS_ON_ICC_DEF = -1;
    private static final int TPLAYER_LENGTH_FOR_PDU = 23;
    private static final long TIMESTAMP_MILLIS = 1149631383000l;
    private static final int SEPTETS_SKT = 80;
    private static final int SEPTETS_KT = 90;
    private static final String LONG_TEXT_WITH_32BIT_CHARS =
        "Long dkkshsh jdjsusj kbsksbdf jfkhcu hhdiwoqiwyrygrvn?*?*!\";:'/,."
        + "__?9#9292736&4;\"$+$+((]\\[\\℅©℅™^®°¥°¥=¢£}}£∆~¶~÷|√×."
        + " 😯😆😉😇😂😀👕🎓😀👙🐕🐀🐶🐰🐩⛪⛲ ";
    private static final String LONG_TEXT_WITH_FLAGS =
        "🇦🇫🇦🇽🇦🇱🇩🇿🇦🇸🇦🇩🇦🇴🇦🇮🇦🇶🇦🇬🇦🇷🇦🇲🇦🇼🇦🇨"
        + "🇦🇺🇦🇹🇦🇿🇧🇸🇧🇭🇧🇩🇧🇧🇧🇾🇧🇪🇧🇿🇧🇯🇧🇲🇧🇹🇧🇴🇧🇦";

    @Before
    public void setUp() throws Exception {
        mTelephonyManager =
            (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
        mPackageManager = getContext().getPackageManager();
    }

    @Test
    public void testCreateFromPdu() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
                || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
            // TODO: temp workaround, need to adjust test to use CDMA pdus
            return;
        }

        String pdu = "07916164260220F0040B914151245584F600006060605130308A04D4F29C0E";
        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
                SmsMessage.FORMAT_3GPP);
        assertEquals(SCA1, sms.getServiceCenterAddress());
        assertEquals(OA1, sms.getOriginatingAddress());
        assertEquals(MESSAGE_BODY1, sms.getMessageBody());
        assertEquals(TPLAYER_LENGTH_FOR_PDU, SmsMessage.getTPLayerLengthForPDU(pdu));
        int[] result = SmsMessage.calculateLength(sms.getMessageBody(), true);
        assertEquals(6, result.length);
        assertEquals(SMS_NUMBER1, result[0]);
        assertEquals(sms.getMessageBody().length(), result[1]);
        assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
        assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
        assertEquals(pdu, TelephonyUtils.toHexString(sms.getPdu()));

        assertEquals(NOT_CREATE_FROM_SIM, sms.getIndexOnSim());
        assertEquals(NOT_CREATE_FROM_ICC, sms.getIndexOnIcc());
        assertEquals(PROTOCOL_IDENTIFIER, sms.getProtocolIdentifier());
        assertFalse(sms.isEmail());
        assertFalse(sms.isReplyPathPresent());
        assertFalse(sms.isStatusReportMessage());
        assertFalse(sms.isCphsMwiMessage());
        assertEquals(SmsMessage.MessageClass.UNKNOWN, sms.getMessageClass());
        assertEquals(STATUS, sms.getStatus());
        assertEquals(STATUS_ON_SIM_DEF, sms.getStatusOnSim());
        assertEquals(STATUS_ON_ICC_DEF, sms.getStatusOnIcc());
        assertEquals(TIMESTAMP_MILLIS, sms.getTimestampMillis());

        // Test create from null Pdu
        sms = SmsMessage.createFromPdu(null, SmsMessage.FORMAT_3GPP);
        assertNull(sms);

        // Test create from long Pdu
        pdu = "07912160130310F2040B915121927786F300036060924180008A0DA"
            + "8695DAC2E8FE9296A794E07";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
        assertEquals(SCA2, sms.getServiceCenterAddress());
        assertEquals(OA2, sms.getOriginatingAddress());
        assertEquals(MESSAGE_BODY2, sms.getMessageBody());
        CharSequence msgBody = sms.getMessageBody();
        result = SmsMessage.calculateLength(msgBody, false);
        assertEquals(6, result.length);
        assertEquals(SMS_NUMBER2, result[0]);
        assertEquals(sms.getMessageBody().length(), result[1]);
        assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
        assertEquals(SmsMessage.ENCODING_7BIT, result[3]);

        // Test createFromPdu Ucs to Sms
        pdu = "07912160130300F4040B914151245584"
            + "F600087010807121352B10212200A900AE00680065006C006C006F";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
        assertEquals(MESSAGE_BODY3, sms.getMessageBody());
        result = SmsMessage.calculateLength(sms.getMessageBody(), true);
        assertEquals(6, result.length);
        assertEquals(SMS_NUMBER3, result[0]);
        assertEquals(sms.getMessageBody().length(), result[1]);
        assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
        assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
    }

    private void assertRemaining(int messageLength, int remaining, int maxChars) {
        if (TelephonyUtils.isSkt(mTelephonyManager)) {
            assertTrue(checkRemaining(SEPTETS_SKT, messageLength, remaining)
                    || checkRemaining(maxChars, messageLength, remaining));
        } else if (TelephonyUtils.isKt(mTelephonyManager)) {
            assertTrue(checkRemaining(SEPTETS_KT, messageLength, remaining)
                    || checkRemaining(maxChars, messageLength, remaining));
        } else {
            assertTrue(checkRemaining(maxChars, messageLength, remaining));
        }
    }

    private boolean checkRemaining(int total, int messageLength, int remaining) {
        return total - messageLength == remaining;
    }

    @Test
    public void testCPHSVoiceMail() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
                || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
            // TODO: temp workaround, need to adjust test to use CDMA pdus
            return;
        }

        // "set MWI flag"
        String pdu = "07912160130310F20404D0110041006060627171118A0120";
        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
                SmsMessage.FORMAT_3GPP);
        assertTrue(sms.isReplace());
        assertEquals(OA3, sms.getOriginatingAddress());
        assertEquals(MESSAGE_BODY4, sms.getMessageBody());
        assertTrue(sms.isMWISetMessage());

        // "clear mwi flag"
        pdu = "07912160130310F20404D0100041006021924193352B0120";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
        assertTrue(sms.isMWIClearMessage());

        // "clear MWI flag"
        pdu = "07912160130310F20404D0100041006060627161058A0120";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
        assertTrue(sms.isReplace());
        assertEquals(OA4, sms.getOriginatingAddress());
        assertEquals(MESSAGE_BODY5, sms.getMessageBody());
        assertTrue(sms.isMWIClearMessage());

        // "set MWI flag"
        pdu = "07912180958750F84401800500C87020026195702B06040102000200";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
        assertTrue(sms.isMWISetMessage());
        assertTrue(sms.isMwiDontStore());

        // "clear mwi flag"
        pdu = "07912180958750F84401800500C07020027160112B06040102000000";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);

        assertTrue(sms.isMWIClearMessage());
        assertTrue(sms.isMwiDontStore());
    }

    @Test
    public void testGetUserData() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
                || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
            // TODO: temp workaround, need to adjust test to use CDMA pdus
            return;
        }

        String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F"
            + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D"
            + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426"
            + "66C414141414D7741414236514141414141008D908918802B3135313232393737"
            + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703"
            + "A2F2F36";
        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
                SmsMessage.FORMAT_3GPP);
        byte[] userData = sms.getUserData();
        assertNotNull(userData);
    }

    @Test
    public void testGetSubmitPdu() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            return;
        }

        SmsMessage.SubmitPdu smsPdu;
        String scAddress = null, destinationAddress = null;
        String message = null;
        boolean statusReportRequested = false;

        // Null message, null destination
        smsPdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress, message,
                statusReportRequested);
        assertNull(smsPdu);

        message = "This is a test message";

        // Non-null message, null destination
        smsPdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress, message,
                statusReportRequested);
        assertNull(smsPdu);

        if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
            // TODO: temp workaround, OCTET encoding for EMS not properly supported
            return;
        }

        scAddress = "1650253000";
        destinationAddress = "18004664411";
        message = "This is a test message";
        statusReportRequested = false;
        smsPdu = SmsMessage.getSubmitPdu(
                scAddress, destinationAddress, message, statusReportRequested);
        assertNotNull(smsPdu);

        smsPdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress, (short)80,
                message.getBytes(), statusReportRequested);
        assertNotNull(smsPdu);
    }

    @Test
    public void testEmailGateway() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
                || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
            // TODO: temp workaround, need to adjust test to use CDMA pdus
            return;
        }

        String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" +
                         "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3";

        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
                SmsMessage.FORMAT_3GPP);
        assertEquals(SCA4, sms.getServiceCenterAddress());
        assertTrue(sms.isEmail());
        assertEquals(EMAIL_ADD, sms.getEmailFrom());
        assertEquals(EMAIL_ADD, sms.getDisplayOriginatingAddress());
        assertEquals(PSEUDO_SUBJECT, sms.getPseudoSubject());

        assertEquals(DISPLAY_MESSAGE_BODY, sms.getDisplayMessageBody());
        assertEquals(DISPLAY_MESSAGE_BODY, sms.getEmailBody());

        pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" +
                        "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
        assertEquals(SCA3, sms.getServiceCenterAddress());
        assertTrue(sms.isEmail());
        assertEquals(OA, sms.getDisplayOriginatingAddress());
        assertEquals(EMAIL_FROM, sms.getEmailFrom());
        assertEquals(DMB, sms.getDisplayMessageBody());
        assertEquals(MB, sms.getEmailBody());
    }

    @Test
    public void testCalculateLength() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            return;
        }

        int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_32BIT_CHARS, false);
        assertEquals(6, result.length);
        assertEquals(3, result[0]);
        assertEquals(LONG_TEXT_WITH_32BIT_CHARS.length(), result[1]);
        // 3 parts, each with (SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2) 16-bit
        // characters. We need to subtract one because a 32-bit character crosses the
        // boundary of 2 parts.
        int preMaxChars = 3 * SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2 - 1;
        // If EMS is not supported, break down EMS into single segment SMS
        // and add page info "x/y".
        // In the case of UCS2 encoding type, we need 8 bytes for this
        // but we only have 6 bytes from UDH, so truncate the limit for
        // each segment by 2 bytes (1 char). This log sms has three segments,
        // so truncate the limit by 3 char in total
        int maxChars = SmsMessage.hasEmsSupport() ? preMaxChars : preMaxChars - 3;
        assertRemaining(LONG_TEXT_WITH_32BIT_CHARS.length(), result[2],
                maxChars);
        assertEquals(SmsMessage.ENCODING_16BIT, result[3]);
    }

    @Test
    public void testCalculateLengthFlags() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            return;
        }
        int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_FLAGS, false);
        assertEquals(2, result[0]);
    }

    @Test
    public void testGetSmsPdu() {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            return;
        }

        SmsMessage.SubmitPdu smsPdu;
        String scAddress = null;
        String destinationAddress = null;
        String message = null;

        // Null message, null destination
        smsPdu = SmsMessage.getSmsPdu(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
                SmsManager.STATUS_ON_ICC_READ,
                scAddress, destinationAddress, message, System.currentTimeMillis());
        assertNull(smsPdu);

        message = "This is a test message";

        // Non-null message, null destination
        smsPdu = SmsMessage.getSmsPdu(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
                SmsManager.STATUS_ON_ICC_READ,
                scAddress, destinationAddress, message, System.currentTimeMillis());
        assertNull(smsPdu);

        if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
            // TODO: temp workaround, OCTET encoding for EMS not properly supported
            return;
        }

        scAddress = "1650253000";
        destinationAddress = "18004664411";
        message = "This is a test message";
        smsPdu = SmsMessage.getSmsPdu(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
                SmsManager.STATUS_ON_ICC_READ,
                scAddress, destinationAddress, message, System.currentTimeMillis());
        assertNotNull(smsPdu);
    }

    @Test
    public void testGetSubmitPduEncodedMessage() throws Exception {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            return;
        }
        String destinationAddress = "18004664411";
        String message = "This is a test message";

        byte[] gsmMsg = SmsMessage.getSubmitPduEncodedMessage(true, destinationAddress,
                message,
                1, // Encoding code unit size. Pick ENCODING_7BIT here.
                0, // GSM national language table. It's usually 0.
                0, // GSM national language table. It's usually 0.
                1, // Reference number of concatenated SMS. Pick 1 for simplicity.
                1, // Sequence number of concatenated SMS. Pick 1 for simplicity.
                2); // Count of messages of concatenated SMS. Pick 2 for simplicity.

        // Encoded gsm message.
        byte[] expectedGsmMsg = {65, 0, 11, -127, -127, 0, 100, 70, 20, -15, 0, 0, 29, 5, 0, 3, 1,
                2, 1, -88, -24, -12, 28, -108, -98, -125, -62, 32, 122, 121, 78, 7, -75, -53, -13,
                121, -8, 92, 6};

        // See comments for gsmMsg.
        byte[] cdmaMsg = SmsMessage.getSubmitPduEncodedMessage(false, destinationAddress,
                message, 1, 0, 0, 1, 1, 2);

        // Encoded cdma message.
        byte[] expectedCdmaMsg = {0, 0, 16, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 1, 8, 10, 10,
                4, 6, 6, 4, 4, 1, 1, 0, 0, 0, 35, 0, 3, 32, 0, 24, 1, 28, 72, -24, 40, 0, 24, 8, 16,
                13, 71, 71, -96, -28, -92, -12, 30, 17, 3, -45, -54, 112, 61, -82, 95, -101, -49,
                -62, -32, 48};

        assertArrayEquals(expectedGsmMsg, gsmMsg);
        // In CDMA, the message byte array is affected by the messageId generated by
        // {@link com.android.internal.telephony.cdma.SmsMessage#getNextMessageId()}
        // which is not consistent. Skip the 2 bytes which are affected by it.
        assertArrayEquals(Arrays.copyOfRange(expectedCdmaMsg, 0, 35),
                Arrays.copyOfRange(cdmaMsg, 0, 35));
        assertArrayEquals(Arrays.copyOfRange(expectedCdmaMsg, 37, expectedCdmaMsg.length),
                Arrays.copyOfRange(cdmaMsg, 37, expectedCdmaMsg.length));
    }

    @Test
    public void testCreateFromNativeSmsSubmitPdu() {
        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            return;
        }
        // Short message with status RECEIVED_READ and size 0. See 3GPP2 C.S0023 3.4.27
        byte[] submitPdu = {1, 0};
        SmsMessage sms = SmsMessage.createFromNativeSmsSubmitPdu(submitPdu, true);
        assertNull(sms);
    }
}
