/*
 * Copyright (C) 2010 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;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.Telephony.CellBroadcasts;
import android.telephony.CbGeoUtils.Geometry;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

/**
 * Parcelable object containing a received cell broadcast message. There are four different types
 * of Cell Broadcast messages:
 *
 * <ul>
 * <li>opt-in informational broadcasts, e.g. news, weather, stock quotes, sports scores</li>
 * <li>cell information messages, broadcast on channel 50, indicating the current cell name for
 *  roaming purposes (required to display on the idle screen in Brazil)</li>
 * <li>emergency broadcasts for the Japanese Earthquake and Tsunami Warning System (ETWS)</li>
 * <li>emergency broadcasts for the American Commercial Mobile Alert Service (CMAS)</li>
 * </ul>
 *
 * <p>There are also four different CB message formats: GSM, ETWS Primary Notification (GSM only),
 * UMTS, and CDMA. Some fields are only applicable for some message formats. Other fields were
 * unified under a common name, avoiding some names, such as "Message Identifier", that refer to
 * two completely different concepts in 3GPP and CDMA.
 *
 * <p>The GSM/UMTS Message Identifier field is available via {@link #getServiceCategory}, the name
 * of the equivalent field in CDMA. In both cases the service category is a 16-bit value, but 3GPP
 * and 3GPP2 have completely different meanings for the respective values. For ETWS and CMAS, the
 * application should
 *
 * <p>The CDMA Message Identifier field is available via {@link #getSerialNumber}, which is used
 * to detect the receipt of a duplicate message to be discarded. In CDMA, the message ID is
 * unique to the current PLMN. In GSM/UMTS, there is a 16-bit serial number containing a 2-bit
 * Geographical Scope field which indicates whether the 10-bit message code and 4-bit update number
 * are considered unique to the PLMN, to the current cell, or to the current Location Area (or
 * Service Area in UMTS). The relevant values are concatenated into a single String which will be
 * unique if the messages are not duplicates.
 *
 * <p>The SMS dispatcher does not detect duplicate messages. However, it does concatenate the
 * pages of a GSM multi-page cell broadcast into a single SmsCbMessage object.
 *
 * <p>Interested applications with {@code RECEIVE_SMS_PERMISSION} can register to receive
 * {@code SMS_CB_RECEIVED_ACTION} broadcast intents for incoming non-emergency broadcasts.
 * Only system applications such as the CellBroadcastReceiver may receive notifications for
 * emergency broadcasts (ETWS and CMAS). This is intended to prevent any potential for delays or
 * interference with the immediate display of the alert message and playing of the alert sound and
 * vibration pattern, which could be caused by poorly written or malicious non-system code.
 *
 * @hide
 */
@SystemApi
public final class SmsCbMessage implements Parcelable {

    /** @hide */
    public static final String LOG_TAG = "SMSCB";

    /** Cell wide geographical scope with immediate display (GSM/UMTS only). */
    public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0;

    /** PLMN wide geographical scope (GSM/UMTS and all CDMA broadcasts). */
    public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1;

    /** Location / service area wide geographical scope (GSM/UMTS only). */
    public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2;

    /** Cell wide geographical scope (GSM/UMTS only). */
    public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3;

    /** @hide */
    @IntDef(prefix = { "GEOGRAPHICAL_SCOPE_" }, value = {
            GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE,
            GEOGRAPHICAL_SCOPE_PLMN_WIDE,
            GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE,
            GEOGRAPHICAL_SCOPE_CELL_WIDE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface GeographicalScope {}

    /** GSM or UMTS format cell broadcast. */
    public static final int MESSAGE_FORMAT_3GPP = 1;

    /** CDMA format cell broadcast. */
    public static final int MESSAGE_FORMAT_3GPP2 = 2;

    /** @hide */
    @IntDef(prefix = { "MESSAGE_FORMAT_" }, value = {
            MESSAGE_FORMAT_3GPP,
            MESSAGE_FORMAT_3GPP2
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface MessageFormat {}

    /** Normal message priority. */
    public static final int MESSAGE_PRIORITY_NORMAL = 0;

    /** Interactive message priority. */
    public static final int MESSAGE_PRIORITY_INTERACTIVE = 1;

    /** Urgent message priority. */
    public static final int MESSAGE_PRIORITY_URGENT = 2;

    /** Emergency message priority. */
    public static final int MESSAGE_PRIORITY_EMERGENCY = 3;

    /** @hide */
    @IntDef(prefix = { "MESSAGE_PRIORITY_" }, value = {
            MESSAGE_PRIORITY_NORMAL,
            MESSAGE_PRIORITY_INTERACTIVE,
            MESSAGE_PRIORITY_URGENT,
            MESSAGE_PRIORITY_EMERGENCY,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface MessagePriority {}

    /**
     * Integer indicating that the maximum wait time is not set.
     * Based on ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12.
     */
    public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255;

    /** Format of this message (for interpretation of service category values). */
    private final int mMessageFormat;

    /** Geographical scope of broadcast. */
    private final int mGeographicalScope;

    /**
     * Serial number of broadcast (message identifier for CDMA, geographical scope + message code +
     * update number for GSM/UMTS). The serial number plus the location code uniquely identify
     * a cell broadcast for duplicate detection.
     */
    private final int mSerialNumber;

    /**
     * Location identifier for this message. It consists of the current operator MCC/MNC as a
     * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
     * message is not binary 01, the Location Area is included for comparison. If the GS is
     * 00 or 11, the Cell ID is also included. LAC and Cell ID are -1 if not specified.
     */
    @NonNull
    private final SmsCbLocation mLocation;

    /**
     * 16-bit CDMA service category or GSM/UMTS message identifier. For ETWS and CMAS warnings,
     * the information provided by the category is also available via {@link #getEtwsWarningInfo()}
     * or {@link #getCmasWarningInfo()}.
     */
    private final int mServiceCategory;

    /** Message language, as a two-character string, e.g. "en". */
    @Nullable
    private final String mLanguage;

    /** The 8-bit data coding scheme defined in 3GPP TS 23.038 section 4. */
    private final int mDataCodingScheme;

    /** Message body, as a String. */
    @Nullable
    private final String mBody;

    /** Message priority (including emergency priority). */
    private final int mPriority;

    /** ETWS warning notification information (ETWS warnings only). */
    @Nullable
    private final SmsCbEtwsInfo mEtwsWarningInfo;

    /** CMAS warning notification information (CMAS warnings only). */
    @Nullable
    private final SmsCbCmasInfo mCmasWarningInfo;

    /**
     * Geo-Fencing Maximum Wait Time in second, a device shall allow to determine its position
     * meeting operator policy. If the device is unable to determine its position meeting operator
     * policy within the GeoFencing Maximum Wait Time, it shall present the alert to the user and
     * discontinue further positioning determination for the alert.
     */
    private final int mMaximumWaitTimeSec;

    /** UNIX timestamp of when the message was received. */
    private final long mReceivedTimeMillis;

    /** CMAS warning area coordinates. */
    private final List<Geometry> mGeometries;

    private final int mSlotIndex;

    private final int mSubId;

    /**
     * Create a new SmsCbMessage with the specified data.
     * @hide
     */
    public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
            @NonNull SmsCbLocation location, int serviceCategory, @Nullable String language,
            @Nullable String body, int priority, @Nullable SmsCbEtwsInfo etwsWarningInfo,
            @Nullable SmsCbCmasInfo cmasWarningInfo, int slotIndex, int subId) {

        this(messageFormat, geographicalScope, serialNumber, location, serviceCategory, language,
                0, body, priority, etwsWarningInfo, cmasWarningInfo, 0 /* maximumWaitingTime */,
                null /* geometries */, System.currentTimeMillis(), slotIndex, subId);
    }

    /**
     * Create a new {@link SmsCbMessage} with the specified data, including warning area
     * coordinates information.
     */
    public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
                        @NonNull SmsCbLocation location, int serviceCategory,
                        @Nullable String language, int dataCodingScheme, @Nullable String body,
                        int priority, @Nullable SmsCbEtwsInfo etwsWarningInfo,
                        @Nullable SmsCbCmasInfo cmasWarningInfo, int maximumWaitTimeSec,
                        @Nullable List<Geometry> geometries, long receivedTimeMillis, int slotIndex,
                        int subId) {
        mMessageFormat = messageFormat;
        mGeographicalScope = geographicalScope;
        mSerialNumber = serialNumber;
        mLocation = location;
        mServiceCategory = serviceCategory;
        mLanguage = language;
        mDataCodingScheme = dataCodingScheme;
        mBody = body;
        mPriority = priority;
        mEtwsWarningInfo = etwsWarningInfo;
        mCmasWarningInfo = cmasWarningInfo;
        mReceivedTimeMillis = receivedTimeMillis;
        mGeometries = geometries;
        mMaximumWaitTimeSec = maximumWaitTimeSec;
        mSlotIndex = slotIndex;
        mSubId = subId;
    }

    /**
     * Create a new SmsCbMessage object from a Parcel.
     * @hide
     */
    public SmsCbMessage(@NonNull Parcel in) {
        mMessageFormat = in.readInt();
        mGeographicalScope = in.readInt();
        mSerialNumber = in.readInt();
        mLocation = new SmsCbLocation(in);
        mServiceCategory = in.readInt();
        mLanguage = in.readString();
        mDataCodingScheme = in.readInt();
        mBody = in.readString();
        mPriority = in.readInt();
        int type = in.readInt();
        switch (type) {
            case 'E':
                // unparcel ETWS warning information
                mEtwsWarningInfo = new SmsCbEtwsInfo(in);
                mCmasWarningInfo = null;
                break;

            case 'C':
                // unparcel CMAS warning information
                mEtwsWarningInfo = null;
                mCmasWarningInfo = new SmsCbCmasInfo(in);
                break;

            default:
                mEtwsWarningInfo = null;
                mCmasWarningInfo = null;
        }
        mReceivedTimeMillis = in.readLong();
        String geoStr = in.readString();
        mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
        mMaximumWaitTimeSec = in.readInt();
        mSlotIndex = in.readInt();
        mSubId = in.readInt();
    }

    /**
     * Flatten this object into a Parcel.
     *
     * @param dest  The Parcel in which the object should be written.
     * @param flags Additional flags about how the object should be written (ignored).
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mMessageFormat);
        dest.writeInt(mGeographicalScope);
        dest.writeInt(mSerialNumber);
        mLocation.writeToParcel(dest, flags);
        dest.writeInt(mServiceCategory);
        dest.writeString(mLanguage);
        dest.writeInt(mDataCodingScheme);
        dest.writeString(mBody);
        dest.writeInt(mPriority);
        if (mEtwsWarningInfo != null) {
            // parcel ETWS warning information
            dest.writeInt('E');
            mEtwsWarningInfo.writeToParcel(dest, flags);
        } else if (mCmasWarningInfo != null) {
            // parcel CMAS warning information
            dest.writeInt('C');
            mCmasWarningInfo.writeToParcel(dest, flags);
        } else {
            // no ETWS or CMAS warning information
            dest.writeInt('0');
        }
        dest.writeLong(mReceivedTimeMillis);
        dest.writeString(
                mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null);
        dest.writeInt(mMaximumWaitTimeSec);
        dest.writeInt(mSlotIndex);
        dest.writeInt(mSubId);
    }

    @NonNull
    public static final Parcelable.Creator<SmsCbMessage> CREATOR =
            new Parcelable.Creator<SmsCbMessage>() {
        @Override
        public SmsCbMessage createFromParcel(Parcel in) {
            return new SmsCbMessage(in);
        }

        @Override
        public SmsCbMessage[] newArray(int size) {
            return new SmsCbMessage[size];
        }
    };

    /**
     * Return the geographical scope of this message (GSM/UMTS only).
     *
     * @return Geographical scope
     */
    public @GeographicalScope int getGeographicalScope() {
        return mGeographicalScope;
    }

    /**
     * Return the broadcast serial number of broadcast (message identifier for CDMA, or
     * geographical scope + message code + update number for GSM/UMTS). The serial number plus
     * the location code uniquely identify a cell broadcast for duplicate detection.
     *
     * @return the 16-bit CDMA message identifier or GSM/UMTS serial number
     */
    public int getSerialNumber() {
        return mSerialNumber;
    }

    /**
     * Return the location identifier for this message, consisting of the MCC/MNC as a
     * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
     * message is not binary 01, the Location Area is included. If the GS is 00 or 11, the
     * cell ID is also included. The {@link SmsCbLocation} object includes a method to test
     * if the location is included within another location area or within a PLMN and CellLocation.
     *
     * @return the geographical location code for duplicate message detection
     */
    @NonNull
    public android.telephony.SmsCbLocation getLocation() {
        return mLocation;
    }

    /**
     * Return the 16-bit CDMA service category or GSM/UMTS message identifier. The interpretation
     * of the category is radio technology specific. For ETWS and CMAS warnings, the information
     * provided by the category is available via {@link #getEtwsWarningInfo()} or
     * {@link #getCmasWarningInfo()} in a radio technology independent format.
     *
     * @return the radio technology specific service category
     */
    public int getServiceCategory() {
        return mServiceCategory;
    }

    /**
     * Get the ISO-639-1 language code for this message, or null if unspecified
     *
     * @return Language code
     */
    @Nullable
    public String getLanguageCode() {
        return mLanguage;
    }

    /**
     * Get data coding scheme of the message
     *
     * @return The 8-bit data coding scheme defined in 3GPP TS 23.038 section 4.
     */
    public int getDataCodingScheme() {
        return mDataCodingScheme;
    }

    /**
     * Get the body of this message, or null if no body available
     *
     * @return Body, or null
     */
    @Nullable
    public String getMessageBody() {
        return mBody;
    }

    /**
     * Get the warning area coordinates information represented by polygons and circles.
     * @return a list of geometries, or an empty list if there is no coordinate information
     * associated with this message.
     * @hide
     */
    @SystemApi
    @NonNull
    public List<Geometry> getGeometries() {
        if (mGeometries == null) {
            return new ArrayList<>();
        }
        return mGeometries;
    }

    /**
     * Get the Geo-Fencing Maximum Wait Time.
     * @return the time in second.
     */
    public int getMaximumWaitingDuration() {
        return mMaximumWaitTimeSec;
    }

    /**
     * Get the time when this message was received.
     * @return the time in millisecond
     */
    public long getReceivedTime() {
        return mReceivedTimeMillis;
    }

    /**
     * Get the slot index associated with this message.
     * @return the slot index associated with this message
     */
    public int getSlotIndex() {
        return mSlotIndex;
    }

    /**
     * Get the subscription id associated with this message.
     * @return the subscription id associated with this message
     */
    public int getSubscriptionId() {
        return mSubId;
    }

    /**
     * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
     * @return an integer representing 3GPP or 3GPP2 message format
     */
    public @MessageFormat int getMessageFormat() {
        return mMessageFormat;
    }

    /**
     * Get the message priority. Normal broadcasts return {@link #MESSAGE_PRIORITY_NORMAL}
     * and emergency broadcasts return {@link #MESSAGE_PRIORITY_EMERGENCY}. CDMA also may return
     * {@link #MESSAGE_PRIORITY_INTERACTIVE} or {@link #MESSAGE_PRIORITY_URGENT}.
     * @return an integer representing the message priority
     */
    public @MessagePriority int getMessagePriority() {
        return mPriority;
    }

    /**
     * If this is an ETWS warning notification then this method will return an object containing
     * the ETWS warning type, the emergency user alert flag, and the popup flag. If this is an
     * ETWS primary notification (GSM only), there will also be a 7-byte timestamp and 43-byte
     * digital signature. As of Release 10, 3GPP TS 23.041 states that the UE shall ignore the
     * ETWS primary notification timestamp and digital signature if received.
     *
     * @return an SmsCbEtwsInfo object, or null if this is not an ETWS warning notification
     */
    @Nullable
    public SmsCbEtwsInfo getEtwsWarningInfo() {
        return mEtwsWarningInfo;
    }

    /**
     * If this is a CMAS warning notification then this method will return an object containing
     * the CMAS message class, category, response type, severity, urgency and certainty.
     * The message class is always present. Severity, urgency and certainty are present for CDMA
     * warning notifications containing a type 1 elements record and for GSM and UMTS warnings
     * except for the Presidential-level alert category. Category and response type are only
     * available for CDMA notifications containing a type 1 elements record.
     *
     * @return an SmsCbCmasInfo object, or null if this is not a CMAS warning notification
     */
    @Nullable
    public SmsCbCmasInfo getCmasWarningInfo() {
        return mCmasWarningInfo;
    }

    /**
     * Return whether this message is an emergency (PWS) message type.
     * @return true if the message is an emergency notification; false otherwise
     */
    public boolean isEmergencyMessage() {
        return mPriority == MESSAGE_PRIORITY_EMERGENCY;
    }

    /**
     * Return whether this message is an ETWS warning alert.
     * @return true if the message is an ETWS warning notification; false otherwise
     */
    public boolean isEtwsMessage() {
        return mEtwsWarningInfo != null;
    }

    /**
     * Return whether this message is a CMAS warning alert.
     * @return true if the message is a CMAS warning notification; false otherwise
     */
    public boolean isCmasMessage() {
        return mCmasWarningInfo != null;
    }

    @Override
    public String toString() {
        return "SmsCbMessage{geographicalScope=" + mGeographicalScope + ", serialNumber="
                + mSerialNumber + ", location=" + mLocation + ", serviceCategory="
                + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody
                + ", priority=" + mPriority
                + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
                + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "")
                + ", maximumWaitingTime=" + mMaximumWaitTimeSec
                + ", received time=" + mReceivedTimeMillis
                + ", slotIndex = " + mSlotIndex
                + ", geo=" + (mGeometries != null
                ? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null")
                + '}';
    }

    /**
     * Describe the kinds of special objects contained in the marshalled representation.
     * @return a bitmask indicating this Parcelable contains no special objects
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * @return the {@link ContentValues} instance that includes the cell broadcast data.
     */
    @NonNull
    public ContentValues getContentValues() {
        ContentValues cv = new ContentValues(16);
        cv.put(CellBroadcasts.SLOT_INDEX, mSlotIndex);
        cv.put(CellBroadcasts.SUBSCRIPTION_ID, mSubId);
        cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, mGeographicalScope);
        if (mLocation.getPlmn() != null) {
            cv.put(CellBroadcasts.PLMN, mLocation.getPlmn());
        }
        if (mLocation.getLac() != -1) {
            cv.put(CellBroadcasts.LAC, mLocation.getLac());
        }
        if (mLocation.getCid() != -1) {
            cv.put(CellBroadcasts.CID, mLocation.getCid());
        }
        cv.put(CellBroadcasts.SERIAL_NUMBER, getSerialNumber());
        cv.put(CellBroadcasts.SERVICE_CATEGORY, getServiceCategory());
        cv.put(CellBroadcasts.LANGUAGE_CODE, getLanguageCode());
        cv.put(CellBroadcasts.DATA_CODING_SCHEME, getDataCodingScheme());
        cv.put(CellBroadcasts.MESSAGE_BODY, getMessageBody());
        cv.put(CellBroadcasts.MESSAGE_FORMAT, getMessageFormat());
        cv.put(CellBroadcasts.MESSAGE_PRIORITY, getMessagePriority());

        SmsCbEtwsInfo etwsInfo = getEtwsWarningInfo();
        if (etwsInfo != null) {
            cv.put(CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType());
            cv.put(CellBroadcasts.ETWS_IS_PRIMARY, etwsInfo.isPrimary());
        }

        SmsCbCmasInfo cmasInfo = getCmasWarningInfo();
        if (cmasInfo != null) {
            cv.put(CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass());
            cv.put(CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory());
            cv.put(CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType());
            cv.put(CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity());
            cv.put(CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency());
            cv.put(CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty());
        }

        cv.put(CellBroadcasts.RECEIVED_TIME, mReceivedTimeMillis);

        if (mGeometries != null) {
            cv.put(CellBroadcasts.GEOMETRIES, CbGeoUtils.encodeGeometriesToString(mGeometries));
        } else {
            cv.put(CellBroadcasts.GEOMETRIES, (String) null);
        }

        cv.put(CellBroadcasts.MAXIMUM_WAIT_TIME, mMaximumWaitTimeSec);

        return cv;
    }

    /**
     * Create a {@link SmsCbMessage} instance from a row in the cell broadcast database.
     * @param cursor an open SQLite cursor pointing to the row to read
     * @return a {@link SmsCbMessage} instance.
     * @throws IllegalArgumentException if one of the required columns is missing
     */
    @NonNull
    public static SmsCbMessage createFromCursor(@NonNull Cursor cursor) {
        int geoScope = cursor.getInt(
                cursor.getColumnIndexOrThrow(CellBroadcasts.GEOGRAPHICAL_SCOPE));
        int serialNum = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERIAL_NUMBER));
        int category = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERVICE_CATEGORY));
        String language = cursor.getString(
                cursor.getColumnIndexOrThrow(CellBroadcasts.LANGUAGE_CODE));
        String body = cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY));
        int format = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT));
        int priority = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY));
        int slotIndex = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SLOT_INDEX));
        int subId = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SUBSCRIPTION_ID));

        String plmn;
        int plmnColumn = cursor.getColumnIndex(CellBroadcasts.PLMN);
        if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) {
            plmn = cursor.getString(plmnColumn);
        } else {
            plmn = null;
        }

        int lac;
        int lacColumn = cursor.getColumnIndex(CellBroadcasts.LAC);
        if (lacColumn != -1 && !cursor.isNull(lacColumn)) {
            lac = cursor.getInt(lacColumn);
        } else {
            lac = -1;
        }

        int cid;
        int cidColumn = cursor.getColumnIndex(CellBroadcasts.CID);
        if (cidColumn != -1 && !cursor.isNull(cidColumn)) {
            cid = cursor.getInt(cidColumn);
        } else {
            cid = -1;
        }

        SmsCbLocation location = new SmsCbLocation(plmn, lac, cid);

        SmsCbEtwsInfo etwsInfo;
        int etwsWarningTypeColumn = cursor.getColumnIndex(CellBroadcasts.ETWS_WARNING_TYPE);
        int etwsIsPrimaryColumn = cursor.getColumnIndex(CellBroadcasts.ETWS_IS_PRIMARY);
        if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)
                && etwsIsPrimaryColumn != -1 && !cursor.isNull(etwsIsPrimaryColumn)) {
            int warningType = cursor.getInt(etwsWarningTypeColumn);
            boolean isPrimary = cursor.getInt(etwsIsPrimaryColumn) != 0;
            etwsInfo = new SmsCbEtwsInfo(warningType, false, false, isPrimary, null);
        } else {
            etwsInfo = null;
        }

        SmsCbCmasInfo cmasInfo = null;
        int cmasMessageClassColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_MESSAGE_CLASS);
        if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) {
            int messageClass = cursor.getInt(cmasMessageClassColumn);

            int cmasCategory;
            int cmasCategoryColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_CATEGORY);
            if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) {
                cmasCategory = cursor.getInt(cmasCategoryColumn);
            } else {
                cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
            }

            int responseType;
            int cmasResponseTypeColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_RESPONSE_TYPE);
            if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) {
                responseType = cursor.getInt(cmasResponseTypeColumn);
            } else {
                responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
            }

            int severity;
            int cmasSeverityColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_SEVERITY);
            if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) {
                severity = cursor.getInt(cmasSeverityColumn);
            } else {
                severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
            }

            int urgency;
            int cmasUrgencyColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_URGENCY);
            if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) {
                urgency = cursor.getInt(cmasUrgencyColumn);
            } else {
                urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
            }

            int certainty;
            int cmasCertaintyColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_CERTAINTY);
            if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) {
                certainty = cursor.getInt(cmasCertaintyColumn);
            } else {
                certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
            }

            cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity,
                    urgency, certainty);
        }

        String geoStr = cursor.getString(cursor.getColumnIndex(CellBroadcasts.GEOMETRIES));
        List<Geometry> geometries =
                geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;

        long receivedTimeMillis = cursor.getLong(
                cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME));

        int maximumWaitTimeSec = cursor.getInt(
                cursor.getColumnIndexOrThrow(CellBroadcasts.MAXIMUM_WAIT_TIME));

        return new SmsCbMessage(format, geoScope, serialNum, location, category,
                language, 0, body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, geometries,
                receivedTimeMillis, slotIndex, subId);
    }

    /**
     * @return {@code True} if this message needs geo-fencing check.
     */
    public boolean needGeoFencingCheck() {
        return mMaximumWaitTimeSec > 0 && mGeometries != null && !mGeometries.isEmpty();
    }
}
