/*
 * Copyright (C) 2013 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 com.android.internal.telephony;

import android.annotation.UnsupportedAppUsage;
import android.content.ContentValues;
import android.database.Cursor;
import android.util.Pair;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.HexDump;

import java.util.Arrays;
import java.util.Date;

/**
 * Tracker for an incoming SMS message ready to broadcast to listeners.
 * This is similar to {@link com.android.internal.telephony.SMSDispatcher.SmsTracker} used for
 * outgoing messages.
 */
public class InboundSmsTracker {

    // Fields for single and multi-part messages
    private final byte[] mPdu;
    private final long mTimestamp;
    private final int mDestPort;
    private final boolean mIs3gpp2;
    private final boolean mIs3gpp2WapPdu;
    private final String mMessageBody;
    private final boolean mIsClass0;

    // Fields for concatenating multi-part SMS messages
    private final String mAddress;
    private final int mReferenceNumber;
    private final int mSequenceNumber;
    private final int mMessageCount;

    // Fields for deleting this message after delivery
    private String mDeleteWhere;
    private String[] mDeleteWhereArgs;

    /**
     * Copied from SmsMessageBase#getDisplayOriginatingAddress used for blocking messages.
     * DisplayAddress could be email address if this message was from an email gateway, otherwise
     * same as mAddress. Email gateway might set a generic gateway address as the mAddress which
     * could not be used for blocking check and append the display email address at the beginning
     * of the message body. In that case, display email address is only available for the first SMS
     * in the Multi-part SMS.
     */
    private final String mDisplayAddress;

    @VisibleForTesting
    /** Destination port flag bit for no destination port. */
    public static final int DEST_PORT_FLAG_NO_PORT = (1 << 16);

    /** Destination port flag bit to indicate 3GPP format message. */
    private static final int DEST_PORT_FLAG_3GPP = (1 << 17);

    @VisibleForTesting
    /** Destination port flag bit to indicate 3GPP2 format message. */
    public static final int DEST_PORT_FLAG_3GPP2 = (1 << 18);

    @VisibleForTesting
    /** Destination port flag bit to indicate 3GPP2 format WAP message. */
    public static final int DEST_PORT_FLAG_3GPP2_WAP_PDU = (1 << 19);

    /** Destination port mask (16-bit unsigned value on GSM and CDMA). */
    private static final int DEST_PORT_MASK = 0xffff;

    @VisibleForTesting
    public static final String SELECT_BY_REFERENCE = "address=? AND reference_number=? AND "
            + "count=? AND (destination_port & " + DEST_PORT_FLAG_3GPP2_WAP_PDU
            + "=0) AND deleted=0";

    @VisibleForTesting
    public static final String SELECT_BY_REFERENCE_3GPP2WAP = "address=? AND reference_number=? "
            + "AND count=? AND (destination_port & "
            + DEST_PORT_FLAG_3GPP2_WAP_PDU + "=" + DEST_PORT_FLAG_3GPP2_WAP_PDU + ") AND deleted=0";

    /**
     * Create a tracker for a single-part SMS.
     *
     * @param pdu the message PDU
     * @param timestamp the message timestamp
     * @param destPort the destination port
     * @param is3gpp2 true for 3GPP2 format; false for 3GPP format
     * @param is3gpp2WapPdu true for 3GPP2 format WAP PDU; false otherwise
     * @param address originating address
     * @param displayAddress email address if this message was from an email gateway, otherwise same
     *                       as originating address
     */
    public InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2,
            boolean is3gpp2WapPdu, String address, String displayAddress, String messageBody,
            boolean isClass0) {
        mPdu = pdu;
        mTimestamp = timestamp;
        mDestPort = destPort;
        mIs3gpp2 = is3gpp2;
        mIs3gpp2WapPdu = is3gpp2WapPdu;
        mMessageBody = messageBody;
        mAddress = address;
        mDisplayAddress = displayAddress;
        mIsClass0 = isClass0;
        // fields for multi-part SMS
        mReferenceNumber = -1;
        mSequenceNumber = getIndexOffset();     // 0 or 1, depending on type
        mMessageCount = 1;
    }

    /**
     * Create a tracker for a multi-part SMS. Sequence numbers start at 1 for 3GPP and regular
     * concatenated 3GPP2 messages, but CDMA WAP push sequence numbers start at 0. The caller will
     * subtract 1 if necessary so that the sequence number is always 0-based. When loading and
     * saving to the raw table, the sequence number is adjusted if necessary for backwards
     * compatibility.
     *
     * @param pdu the message PDU
     * @param timestamp the message timestamp
     * @param destPort the destination port
     * @param is3gpp2 true for 3GPP2 format; false for 3GPP format
     * @param address originating address, or email if this message was from an email gateway
     * @param displayAddress email address if this message was from an email gateway, otherwise same
     *                       as originating address
     * @param referenceNumber the concatenated reference number
     * @param sequenceNumber the sequence number of this segment (0-based)
     * @param messageCount the total number of segments
     * @param is3gpp2WapPdu true for 3GPP2 format WAP PDU; false otherwise
     */
    public InboundSmsTracker(byte[] pdu, long timestamp, int destPort, boolean is3gpp2,
            String address, String displayAddress, int referenceNumber, int sequenceNumber,
            int messageCount, boolean is3gpp2WapPdu, String messageBody, boolean isClass0) {
        mPdu = pdu;
        mTimestamp = timestamp;
        mDestPort = destPort;
        mIs3gpp2 = is3gpp2;
        mIs3gpp2WapPdu = is3gpp2WapPdu;
        mMessageBody = messageBody;
        mIsClass0 = isClass0;
        // fields used for check blocking message
        mDisplayAddress = displayAddress;
        // fields for multi-part SMS
        mAddress = address;
        mReferenceNumber = referenceNumber;
        mSequenceNumber = sequenceNumber;
        mMessageCount = messageCount;
    }

    /**
     * Create a new tracker from the row of the raw table pointed to by Cursor.
     * Since this constructor is used only for recovery during startup, the Dispatcher is null.
     * @param cursor a Cursor pointing to the row to construct this SmsTracker for
     */
    public InboundSmsTracker(Cursor cursor, boolean isCurrentFormat3gpp2) {
        mPdu = HexDump.hexStringToByteArray(cursor.getString(InboundSmsHandler.PDU_COLUMN));

        // TODO: add a column to raw db to store this
        mIsClass0 = false;

        if (cursor.isNull(InboundSmsHandler.DESTINATION_PORT_COLUMN)) {
            mDestPort = -1;
            mIs3gpp2 = isCurrentFormat3gpp2;
            mIs3gpp2WapPdu = false;
        } else {
            int destPort = cursor.getInt(InboundSmsHandler.DESTINATION_PORT_COLUMN);
            if ((destPort & DEST_PORT_FLAG_3GPP) != 0) {
                mIs3gpp2 = false;
            } else if ((destPort & DEST_PORT_FLAG_3GPP2) != 0) {
                mIs3gpp2 = true;
            } else {
                mIs3gpp2 = isCurrentFormat3gpp2;
            }
            mIs3gpp2WapPdu = ((destPort & DEST_PORT_FLAG_3GPP2_WAP_PDU) != 0);
            mDestPort = getRealDestPort(destPort);
        }

        mTimestamp = cursor.getLong(InboundSmsHandler.DATE_COLUMN);
        mAddress = cursor.getString(InboundSmsHandler.ADDRESS_COLUMN);
        mDisplayAddress = cursor.getString(InboundSmsHandler.DISPLAY_ADDRESS_COLUMN);

        if (cursor.getInt(InboundSmsHandler.COUNT_COLUMN) == 1) {
            // single-part message
            long rowId = cursor.getLong(InboundSmsHandler.ID_COLUMN);
            mReferenceNumber = -1;
            mSequenceNumber = getIndexOffset();     // 0 or 1, depending on type
            mMessageCount = 1;
            mDeleteWhere = InboundSmsHandler.SELECT_BY_ID;
            mDeleteWhereArgs = new String[]{Long.toString(rowId)};
        } else {
            // multi-part message
            mReferenceNumber = cursor.getInt(InboundSmsHandler.REFERENCE_NUMBER_COLUMN);
            mMessageCount = cursor.getInt(InboundSmsHandler.COUNT_COLUMN);

            // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
            mSequenceNumber = cursor.getInt(InboundSmsHandler.SEQUENCE_COLUMN);
            int index = mSequenceNumber - getIndexOffset();

            if (index < 0 || index >= mMessageCount) {
                throw new IllegalArgumentException("invalid PDU sequence " + mSequenceNumber
                        + " of " + mMessageCount);
            }

            mDeleteWhere = getQueryForSegments();
            mDeleteWhereArgs = new String[]{mAddress,
                    Integer.toString(mReferenceNumber), Integer.toString(mMessageCount)};
        }
        mMessageBody = cursor.getString(InboundSmsHandler.MESSAGE_BODY_COLUMN);
    }

    public ContentValues getContentValues() {
        ContentValues values = new ContentValues();
        values.put("pdu", HexDump.toHexString(mPdu));
        values.put("date", mTimestamp);
        // Always set the destination port, since it now contains message format flags.
        // Port is a 16-bit value, or -1, so clear the upper bits before setting flags.
        int destPort;
        if (mDestPort == -1) {
            destPort = DEST_PORT_FLAG_NO_PORT;
        } else {
            destPort = mDestPort & DEST_PORT_MASK;
        }
        if (mIs3gpp2) {
            destPort |= DEST_PORT_FLAG_3GPP2;
        } else {
            destPort |= DEST_PORT_FLAG_3GPP;
        }
        if (mIs3gpp2WapPdu) {
            destPort |= DEST_PORT_FLAG_3GPP2_WAP_PDU;
        }
        values.put("destination_port", destPort);
        if (mAddress != null) {
            values.put("address", mAddress);
            values.put("display_originating_addr", mDisplayAddress);
            values.put("reference_number", mReferenceNumber);
            values.put("sequence", mSequenceNumber);
        }
        values.put("count", mMessageCount);
        values.put("message_body", mMessageBody);
        return values;
    }

    /**
     * Get the port number, or -1 if there is no destination port.
     * @param destPort the destination port value, with flags
     * @return the real destination port, or -1 for no port
     */
    public static int getRealDestPort(int destPort) {
        if ((destPort & DEST_PORT_FLAG_NO_PORT) != 0) {
            return -1;
        } else {
           return destPort & DEST_PORT_MASK;
        }
    }

    /**
     * Update the values to delete all rows of the message from raw table.
     * @param deleteWhere the selection to use
     * @param deleteWhereArgs the selection args to use
     */
    public void setDeleteWhere(String deleteWhere, String[] deleteWhereArgs) {
        mDeleteWhere = deleteWhere;
        mDeleteWhereArgs = deleteWhereArgs;
    }

    public String toString() {
        StringBuilder builder = new StringBuilder("SmsTracker{timestamp=");
        builder.append(new Date(mTimestamp));
        builder.append(" destPort=").append(mDestPort);
        builder.append(" is3gpp2=").append(mIs3gpp2);
        if (InboundSmsHandler.VDBG) {
            builder.append(" address=").append(mAddress);
            builder.append(" timestamp=").append(mTimestamp);
            builder.append(" messageBody=").append(mMessageBody);
        }
        builder.append(" display_originating_addr=").append(mDisplayAddress);
        builder.append(" refNumber=").append(mReferenceNumber);
        builder.append(" seqNumber=").append(mSequenceNumber);
        builder.append(" msgCount=").append(mMessageCount);
        if (mDeleteWhere != null) {
            builder.append(" deleteWhere(").append(mDeleteWhere);
            builder.append(") deleteArgs=(").append(Arrays.toString(mDeleteWhereArgs));
            builder.append(')');
        }
        builder.append('}');
        return builder.toString();
    }

    public byte[] getPdu() {
        return mPdu;
    }

    public long getTimestamp() {
        return mTimestamp;
    }

    public int getDestPort() {
        return mDestPort;
    }

    public boolean is3gpp2() {
        return mIs3gpp2;
    }

    public boolean isClass0() {
        return mIsClass0;
    }

    @UnsupportedAppUsage
    public String getFormat() {
        return mIs3gpp2 ? SmsConstants.FORMAT_3GPP2 : SmsConstants.FORMAT_3GPP;
    }

    public String getQueryForSegments() {
        return mIs3gpp2WapPdu ? SELECT_BY_REFERENCE_3GPP2WAP : SELECT_BY_REFERENCE;
    }

    /**
     * Get the query to find the exact same message/message segment in the db.
     * @return Pair with where as Pair.first and whereArgs as Pair.second
     */
    public Pair<String, String[]> getExactMatchDupDetectQuery() {
        // convert to strings for query
        String address = getAddress();
        String refNumber = Integer.toString(getReferenceNumber());
        String count = Integer.toString(getMessageCount());
        String seqNumber = Integer.toString(getSequenceNumber());
        String date = Long.toString(getTimestamp());
        String messageBody = getMessageBody();

        String where = "address=? AND reference_number=? AND count=? AND sequence=? AND "
                + "date=? AND message_body=?";
        where = addDestPortQuery(where);
        String[] whereArgs = new String[]{address, refNumber, count, seqNumber, date, messageBody};

        return new Pair<>(where, whereArgs);
    }

    /**
     * The key differences here compared to exact match are:
     * - this is applicable only for multi-part message segments
     * - this does not match date or message_body
     * - this matches deleted=0 (undeleted segments)
     * The only difference as compared to getQueryForSegments() is that this checks for sequence as
     * well.
     * @return Pair with where as Pair.first and whereArgs as Pair.second
     */
    public Pair<String, String[]> getInexactMatchDupDetectQuery() {
        if (getMessageCount() == 1) return null;

        // convert to strings for query
        String address = getAddress();
        String refNumber = Integer.toString(getReferenceNumber());
        String count = Integer.toString(getMessageCount());
        String seqNumber = Integer.toString(getSequenceNumber());

        String where = "address=? AND reference_number=? AND count=? AND sequence=? AND "
                + "deleted=0";
        where = addDestPortQuery(where);
        String[] whereArgs = new String[]{address, refNumber, count, seqNumber};

        return new Pair<>(where, whereArgs);
    }

    private String addDestPortQuery(String where) {
        String whereDestPort;
        if (mIs3gpp2WapPdu) {
            whereDestPort = "destination_port & " + DEST_PORT_FLAG_3GPP2_WAP_PDU + "="
                + DEST_PORT_FLAG_3GPP2_WAP_PDU;
        } else {
            whereDestPort = "destination_port & " + DEST_PORT_FLAG_3GPP2_WAP_PDU + "=0";
        }
        return where + " AND (" + whereDestPort + ")";
    }

    /**
     * Sequence numbers for concatenated messages start at 1. The exception is CDMA WAP PDU
     * messages, which use a 0-based index.
     * @return the offset to use to convert between mIndex and the sequence number
     */
    @UnsupportedAppUsage
    public int getIndexOffset() {
        return (mIs3gpp2 && mIs3gpp2WapPdu) ? 0 : 1;
    }

    public String getAddress() {
        return mAddress;
    }

    public String getDisplayAddress() {
        return mDisplayAddress;
    }

    public String getMessageBody() {
        return mMessageBody;
    }

    public int getReferenceNumber() {
        return mReferenceNumber;
    }

    public int getSequenceNumber() {
        return mSequenceNumber;
    }

    public int getMessageCount() {
        return mMessageCount;
    }

    public String getDeleteWhere() {
        return mDeleteWhere;
    }

    public String[] getDeleteWhereArgs() {
        return mDeleteWhereArgs;
    }
}
