/*
 * 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 static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;

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 {
        assumeTrue(getContext().getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_TELEPHONY_MESSAGING));
        mPackageManager = getContext().getPackageManager();
        mTelephonyManager =
            (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
    }

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

        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]);

        // Test createFromPdu to test ENCODING_KSC5601 (0x84 as DCS in pdu)
        // The only way of retrieving the Data Coding Scheme is via SmsMessage#calculateLength,
        // but it never returns ENCODING_KSC5601, so we're testing for ENCODING_16BIT instead.
        pdu = "07916164260220F0040B914151245584F600846060605130308A04D4F29C0E";
        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
        result = SmsMessage.calculateLength(sms.getMessageBody(), false);
        assertEquals(SmsMessage.ENCODING_16BIT, 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 {
        // TODO: temp workaround, need to adjust test to use CDMA pdus
        assumeFalse(mPackageManager.hasSystemFeature(
                PackageManager.FEATURE_TELEPHONY_CDMA));

        // "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 {
        // TODO: temp workaround, need to adjust test to use CDMA pdus
        assumeFalse(mPackageManager.hasSystemFeature(
                PackageManager.FEATURE_TELEPHONY_CDMA));

        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 {
        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 {
        // TODO: temp workaround, need to adjust test to use CDMA pdus
        assumeFalse(mPackageManager.hasSystemFeature(
                PackageManager.FEATURE_TELEPHONY_CDMA));

        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 {
        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 {
        int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_FLAGS, false);
        assertEquals(2, result[0]);
    }

    @Test
    public void testGetSmsPdu() {
        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 {
        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() {
        // 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);
    }
}
