/*
 * Copyright (C) 2018 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.emergency;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.hardware.radio.V1_4.EmergencyNumberSource;
import android.hardware.radio.V1_4.EmergencyServiceCategory;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * A parcelable class that wraps and retrieves the information of number, service category(s) and
 * country code for a specific emergency number.
 */
public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNumber> {

    private static final String LOG_TAG = "EmergencyNumber";

    /**
     * Defining Emergency Service Category as follows:
     *  - General emergency call, all categories;
     *  - Police;
     *  - Ambulance;
     *  - Fire Brigade;
     *  - Marine Guard;
     *  - Mountain Rescue;
     *  - Manually Initiated eCall (MIeC);
     *  - Automatically Initiated eCall (AIeC);
     *
     * Category UNSPECIFIED (General emergency call, all categories) indicates that no specific
     * services are associated with this emergency number; if the emergency number is specified,
     * it has one or more defined emergency service categories.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     *
     * @hide
     */
    @IntDef(flag = true, prefix = { "EMERGENCY_SERVICE_CATEGORY_" }, value = {
            EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
            EMERGENCY_SERVICE_CATEGORY_POLICE,
            EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
            EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
            EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD,
            EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE,
            EMERGENCY_SERVICE_CATEGORY_MIEC,
            EMERGENCY_SERVICE_CATEGORY_AIEC
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EmergencyServiceCategories {}

    /**
     * Emergency Service Category UNSPECIFIED (General emergency call, all categories) bit-field
     * indicates that no specific services are associated with this emergency number; if the
     * emergency number is specified, it has one or more defined emergency service categories.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED =
            EmergencyServiceCategory.UNSPECIFIED;
    /**
     * Bit-field that indicates Emergency Service Category for Police.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_POLICE = EmergencyServiceCategory.POLICE;
    /**
     * Bit-field that indicates Emergency Service Category for Ambulance.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_AMBULANCE =
            EmergencyServiceCategory.AMBULANCE;
    /**
     * Bit-field that indicates Emergency Service Category for Fire Brigade.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE =
            EmergencyServiceCategory.FIRE_BRIGADE;
    /**
     * Bit-field that indicates Emergency Service Category for Marine Guard.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD =
            EmergencyServiceCategory.MARINE_GUARD;
    /**
     * Bit-field that indicates Emergency Service Category for Mountain Rescue.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE =
            EmergencyServiceCategory.MOUNTAIN_RESCUE;
    /**
     * Bit-field that indicates Emergency Service Category for Manually Initiated eCall (MIeC)
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_MIEC = EmergencyServiceCategory.MIEC;
    /**
     * Bit-field that indicates Emergency Service Category for Automatically Initiated eCall (AIeC)
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_SERVICE_CATEGORY_AIEC = EmergencyServiceCategory.AIEC;

    private static final Set<Integer> EMERGENCY_SERVICE_CATEGORY_SET;
    static {
        EMERGENCY_SERVICE_CATEGORY_SET = new HashSet<Integer>();
        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_POLICE);
        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE);
        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD);
        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE);
        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MIEC);
        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_AIEC);
    }

    /**
     * The source to tell where the corresponding @1.4::EmergencyNumber comes from.
     *
     * The emergency number has one or more defined emergency number sources.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     *
     * @hide
     */
    @IntDef(flag = true, prefix = { "EMERGENCY_NUMBER_SOURCE_" }, value = {
            EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
            EMERGENCY_NUMBER_SOURCE_SIM,
            EMERGENCY_NUMBER_SOURCE_DATABASE,
            EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
            EMERGENCY_NUMBER_SOURCE_DEFAULT
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EmergencyNumberSources {}

    /**
     * Bit-field which indicates the number is from the network signaling.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING =
            EmergencyNumberSource.NETWORK_SIGNALING;
    /**
     * Bit-field which indicates the number is from the sim.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_NUMBER_SOURCE_SIM = EmergencyNumberSource.SIM;
    /**
     * Bit-field which indicates the number is from the platform-maintained database.
     */
    public static final int EMERGENCY_NUMBER_SOURCE_DATABASE =  1 << 4;
    /**
     * Bit-field which indicates the number is from test mode.
     *
     * @hide
     */
    public static final int EMERGENCY_NUMBER_SOURCE_TEST =  1 << 5;
    /** Bit-field which indicates the number is from the modem config. */
    public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG =
            EmergencyNumberSource.MODEM_CONFIG;
    /**
     * Bit-field which indicates the number is available as default.
     *
     * 112, 911 must always be available; additionally, 000, 08, 110, 999, 118 and 119 must be
     * available when sim is not present.
     *
     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
     */
    public static final int EMERGENCY_NUMBER_SOURCE_DEFAULT = EmergencyNumberSource.DEFAULT;

    private static final Set<Integer> EMERGENCY_NUMBER_SOURCE_SET;
    static {
        EMERGENCY_NUMBER_SOURCE_SET = new HashSet<Integer>();
        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_SIM);
        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_DATABASE);
        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_DEFAULT);
    }

    /**
     * Indicated the framework does not know whether an emergency call should be placed using
     * emergency or normal call routing. This means the underlying radio or IMS implementation is
     * free to determine for itself how to route the call.
     */
    public static final int EMERGENCY_CALL_ROUTING_UNKNOWN = 0;
    /**
     * Indicates the radio or IMS implementation must handle the call through emergency routing.
     */
    public static final int EMERGENCY_CALL_ROUTING_EMERGENCY = 1;
    /**
     * Indicates the radio or IMS implementation must handle the call through normal call routing.
     */
    public static final int EMERGENCY_CALL_ROUTING_NORMAL = 2;

    /**
     * The routing to tell how to handle the call for the corresponding emergency number.
     *
     * @hide
     */
    @IntDef(flag = false, prefix = { "EMERGENCY_CALL_ROUTING_" }, value = {
            EMERGENCY_CALL_ROUTING_UNKNOWN,
            EMERGENCY_CALL_ROUTING_EMERGENCY,
            EMERGENCY_CALL_ROUTING_NORMAL
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EmergencyCallRouting {}


    private final String mNumber;
    private final String mCountryIso;
    private final String mMnc;
    private final int mEmergencyServiceCategoryBitmask;
    private final List<String> mEmergencyUrns;
    private final int mEmergencyNumberSourceBitmask;
    private final int mEmergencyCallRouting;

    /** @hide */
    public EmergencyNumber(@NonNull String number, @NonNull String countryIso, @NonNull String mnc,
                           @EmergencyServiceCategories int emergencyServiceCategories,
                           @NonNull List<String> emergencyUrns,
                           @EmergencyNumberSources int emergencyNumberSources,
                           @EmergencyCallRouting int emergencyCallRouting) {
        this.mNumber = number;
        this.mCountryIso = countryIso;
        this.mMnc = mnc;
        this.mEmergencyServiceCategoryBitmask = emergencyServiceCategories;
        this.mEmergencyUrns = emergencyUrns;
        this.mEmergencyNumberSourceBitmask = emergencyNumberSources;
        this.mEmergencyCallRouting = emergencyCallRouting;
    }

    /** @hide */
    public EmergencyNumber(Parcel source) {
        mNumber = source.readString();
        mCountryIso = source.readString();
        mMnc = source.readString();
        mEmergencyServiceCategoryBitmask = source.readInt();
        mEmergencyUrns = source.createStringArrayList();
        mEmergencyNumberSourceBitmask = source.readInt();
        mEmergencyCallRouting = source.readInt();
    }

    @Override
    /** @hide */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mNumber);
        dest.writeString(mCountryIso);
        dest.writeString(mMnc);
        dest.writeInt(mEmergencyServiceCategoryBitmask);
        dest.writeStringList(mEmergencyUrns);
        dest.writeInt(mEmergencyNumberSourceBitmask);
        dest.writeInt(mEmergencyCallRouting);
    }

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

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

    /**
     * Get the dialing number of the emergency number.
     *
     * The character in the number string is only the dial pad
     * character('0'-'9', '*', '+', or '#'). For example: 911.
     *
     * @return the dialing number.
     */
    public @NonNull String getNumber() {
        return mNumber;
    }

    /**
     * Get the country code string (lowercase character) in ISO 3166 format of the emergency number.
     *
     * @return the country code string (lowercase character) in ISO 3166 format.
     */
    public @NonNull String getCountryIso() {
        return mCountryIso;
    }

    /**
     * Get the Mobile Network Code of the emergency number.
     *
     * @return the Mobile Network Code of the emergency number.
     */
    public @NonNull String getMnc() {
        return mMnc;
    }

    /**
     * Returns the bitmask of emergency service categories of the emergency number.
     *
     * @return bitmask of the emergency service categories
     *
     * @hide
     */
    public @EmergencyServiceCategories int getEmergencyServiceCategoryBitmask() {
        return mEmergencyServiceCategoryBitmask;
    }

    /**
     * Returns the bitmask of emergency service categories of the emergency number for
     * internal dialing.
     *
     * @return bitmask of the emergency service categories
     *
     * @hide
     */
    public @EmergencyServiceCategories int getEmergencyServiceCategoryBitmaskInternalDial() {
        if (mEmergencyNumberSourceBitmask == EMERGENCY_NUMBER_SOURCE_DATABASE) {
            return EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
        }
        return mEmergencyServiceCategoryBitmask;
    }

    /**
     * Returns the emergency service categories of the emergency number.
     *
     * Note: if the emergency number is in {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}, only
     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} is returned and it means the number is in
     * all categories.
     *
     * @return a list of the emergency service categories
     */
    public @NonNull List<Integer> getEmergencyServiceCategories() {
        List<Integer> categories = new ArrayList<>();
        if (serviceUnspecified()) {
            categories.add(EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED);
            return categories;
        }
        for (Integer category : EMERGENCY_SERVICE_CATEGORY_SET) {
            if (isInEmergencyServiceCategories(category)) {
                categories.add(category);
            }
        }
        return categories;
    }

    /**
     * Returns the list of emergency Uniform Resources Names (URN) of the emergency number.
     *
     * For example, {@code urn:service:sos} is the generic URN for contacting emergency services
     * of all type.
     *
     * Reference: 3gpp 24.503, Section 5.1.6.8.1 - General;
     *            RFC 5031
     *
     * @return list of emergency Uniform Resources Names (URN) or an empty list if the emergency
     *         number does not have a specified emergency Uniform Resource Name.
     */
    public @NonNull List<String> getEmergencyUrns() {
        return Collections.unmodifiableList(mEmergencyUrns);
    }

    /**
     * Checks if the emergency service category is unspecified for the emergency number
     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}.
     *
     * @return {@code true} if the emergency service category is unspecified for the emergency
     * number {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}; {@code false} otherwise.
     */
    private boolean serviceUnspecified() {
        return mEmergencyServiceCategoryBitmask == EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
    }

    /**
     * Checks if the emergency number is in the supplied emergency service category(s).
     *
     * @param categories - the supplied emergency service categories
     *
     * @return {@code true} if the emergency number is in the specified emergency service
     * category(s) or if its emergency service category is
     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}; {@code false} otherwise.
     */
    public boolean isInEmergencyServiceCategories(@EmergencyServiceCategories int categories) {
        if (categories == EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED) {
            return serviceUnspecified();
        }
        if (serviceUnspecified()) {
            return true;
        }
        return (mEmergencyServiceCategoryBitmask & categories) == categories;
    }

    /**
     * Returns the bitmask of the sources of the emergency number.
     *
     * @return bitmask of the emergency number sources
     *
     * @hide
     */
    public @EmergencyNumberSources int getEmergencyNumberSourceBitmask() {
        return mEmergencyNumberSourceBitmask;
    }

    /**
     * Returns a list of sources of the emergency number.
     *
     * @return a list of emergency number sources
     */
    public @NonNull List<Integer> getEmergencyNumberSources() {
        List<Integer> sources = new ArrayList<>();
        for (Integer source : EMERGENCY_NUMBER_SOURCE_SET) {
            if ((mEmergencyNumberSourceBitmask & source) == source) {
                sources.add(source);
            }
        }
        return sources;
    }

    /**
     * Checks if the emergency number is from the specified emergency number source(s).
     *
     * @return {@code true} if the emergency number is from the specified emergency number
     * source(s); {@code false} otherwise.
     *
     * @param sources - the supplied emergency number sources
     */
    public boolean isFromSources(@EmergencyNumberSources int sources) {
        return (mEmergencyNumberSourceBitmask & sources) == sources;
    }

    /**
     * Returns the emergency call routing information.
     *
     * <p>Some regions require some emergency numbers which are not routed using typical emergency
     * call processing, but are instead placed as regular phone calls. The emergency call routing
     * field provides information about how an emergency call will be routed when it is placed.
     *
     * @return the emergency call routing requirement
     */
    public @EmergencyCallRouting int getEmergencyCallRouting() {
        return mEmergencyCallRouting;
    }

    @Override
    /** @hide */
    public int describeContents() {
        return 0;
    }

    @Override
    public String toString() {
        return "EmergencyNumber:" + "Number-" + mNumber + "|CountryIso-" + mCountryIso
                + "|Mnc-" + mMnc
                + "|ServiceCategories-" + Integer.toBinaryString(mEmergencyServiceCategoryBitmask)
                + "|Urns-" + mEmergencyUrns
                + "|Sources-" + Integer.toBinaryString(mEmergencyNumberSourceBitmask)
                + "|Routing-" + Integer.toBinaryString(mEmergencyCallRouting);
    }

    @Override
    public boolean equals(Object o) {
        if (!EmergencyNumber.class.isInstance(o)) {
            return false;
        }
        EmergencyNumber other = (EmergencyNumber) o;
        return mNumber.equals(other.mNumber)
                && mCountryIso.equals(other.mCountryIso)
                && mMnc.equals(other.mMnc)
                && mEmergencyServiceCategoryBitmask == other.mEmergencyServiceCategoryBitmask
                && mEmergencyUrns.equals(other.mEmergencyUrns)
                && mEmergencyNumberSourceBitmask == other.mEmergencyNumberSourceBitmask
                && mEmergencyCallRouting == other.mEmergencyCallRouting;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mNumber, mCountryIso, mMnc, mEmergencyServiceCategoryBitmask,
                mEmergencyUrns, mEmergencyNumberSourceBitmask, mEmergencyCallRouting);
    }

    /**
     * Calculate the score for display priority.
     *
     * A higher display priority score means the emergency number has a higher display priority.
     * The score is higher if the source is defined for a higher display priority.
     *
     * The priority of sources are defined as follows:
     *     EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING >
     *     EMERGENCY_NUMBER_SOURCE_SIM >
     *     EMERGENCY_NUMBER_SOURCE_DATABASE >
     *     EMERGENCY_NUMBER_SOURCE_DEFAULT >
     *     EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
     *
     */
    private int getDisplayPriorityScore() {
        int score = 0;
        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING)) {
            score += 1 << 4;
        }
        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_SIM)) {
            score += 1 << 3;
        }
        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_DATABASE)) {
            score += 1 << 2;
        }
        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_DEFAULT)) {
            score += 1 << 1;
        }
        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG)) {
            score += 1 << 0;
        }
        return score;
    }

    /**
     * Compare the display priority for this emergency number and the supplied emergency number.
     *
     * @param emergencyNumber the supplied emergency number
     * @return a negative value if the supplied emergency number has a lower display priority;
     *         a positive value if the supplied emergency number has a higher display priority;
     *         0 if both have equal display priority.
     */
    @Override
    public int compareTo(@NonNull EmergencyNumber emergencyNumber) {
        if (this.getDisplayPriorityScore()
                > emergencyNumber.getDisplayPriorityScore()) {
            return -1;
        } else if (this.getDisplayPriorityScore()
                < emergencyNumber.getDisplayPriorityScore()) {
            return 1;
        } else if (this.getNumber().compareTo(emergencyNumber.getNumber()) != 0) {
            return this.getNumber().compareTo(emergencyNumber.getNumber());
        } else if (this.getCountryIso().compareTo(emergencyNumber.getCountryIso()) != 0) {
            return this.getCountryIso().compareTo(emergencyNumber.getCountryIso());
        } else if (this.getMnc().compareTo(emergencyNumber.getMnc()) != 0) {
            return this.getMnc().compareTo(emergencyNumber.getMnc());
        } else if (this.getEmergencyServiceCategoryBitmask()
                != emergencyNumber.getEmergencyServiceCategoryBitmask()) {
            return this.getEmergencyServiceCategoryBitmask()
                    > emergencyNumber.getEmergencyServiceCategoryBitmask() ? -1 : 1;
        } else if (this.getEmergencyUrns().toString().compareTo(
                emergencyNumber.getEmergencyUrns().toString()) != 0) {
            return this.getEmergencyUrns().toString().compareTo(
                    emergencyNumber.getEmergencyUrns().toString());
        } else if (this.getEmergencyCallRouting()
                != emergencyNumber.getEmergencyCallRouting()) {
            return this.getEmergencyCallRouting()
                    > emergencyNumber.getEmergencyCallRouting() ? -1 : 1;
        } else {
            return 0;
        }
    }

    /**
     * In-place merge same emergency numbers in the emergency number list.
     *
     * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' and
     * 'categories' fields. Multiple Emergency Number Sources should be merged into one bitfield
     * for the same EmergencyNumber.
     *
     * @param emergencyNumberList the emergency number list to process
     *
     * @hide
     */
    public static void mergeSameNumbersInEmergencyNumberList(
            List<EmergencyNumber> emergencyNumberList) {
        if (emergencyNumberList == null) {
            return;
        }
        Set<Integer> duplicatedEmergencyNumberPosition = new HashSet<>();
        for (int i = 0; i < emergencyNumberList.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (areSameEmergencyNumbers(
                        emergencyNumberList.get(i), emergencyNumberList.get(j))) {
                    Rlog.e(LOG_TAG, "Found unexpected duplicate numbers: "
                            + emergencyNumberList.get(i) + " vs " + emergencyNumberList.get(j));
                    // Set the merged emergency number in the current position
                    emergencyNumberList.set(i, mergeSameEmergencyNumbers(
                            emergencyNumberList.get(i), emergencyNumberList.get(j)));
                    // Mark the emergency number has been merged
                    duplicatedEmergencyNumberPosition.add(j);
                }
            }
        }

        // Remove the marked emergency number in the original list
        for (int i = emergencyNumberList.size() - 1; i >= 0; i--) {
            if (duplicatedEmergencyNumberPosition.contains(i)) {
                emergencyNumberList.remove(i);
            }
        }
        Collections.sort(emergencyNumberList);
    }

    /**
     * Check if two emergency numbers are the same.
     *
     * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' and
     * 'categories', and 'routing' fields. Multiple Emergency Number Sources should be
     * merged into one bitfield for the same EmergencyNumber.
     *
     * @param first first EmergencyNumber to compare
     * @param second second EmergencyNumber to compare
     * @return true if they are the same EmergencyNumbers; false otherwise.
     *
     * @hide
     */
    public static boolean areSameEmergencyNumbers(@NonNull EmergencyNumber first,
                                                  @NonNull EmergencyNumber second) {
        if (!first.getNumber().equals(second.getNumber())) {
            return false;
        }
        if (!first.getCountryIso().equals(second.getCountryIso())) {
            return false;
        }
        if (!first.getMnc().equals(second.getMnc())) {
            return false;
        }
        if (first.getEmergencyServiceCategoryBitmask()
                != second.getEmergencyServiceCategoryBitmask()) {
            return false;
        }
        if (!first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
            return false;
        }
        if (first.getEmergencyCallRouting() != second.getEmergencyCallRouting()) {
            return false;
        }
        // Never merge two numbers if one of them is from test mode but the other one is not;
        // This supports to remove a number from the test mode.
        if (first.isFromSources(EMERGENCY_NUMBER_SOURCE_TEST)
                ^ second.isFromSources(EMERGENCY_NUMBER_SOURCE_TEST)) {
            return false;
        }
        return true;
    }

    /**
     * Get a merged EmergencyNumber from two same emergency numbers. Two emergency numbers are
     * the same if {@link #areSameEmergencyNumbers} returns {@code true}.
     *
     * @param first first EmergencyNumber to compare
     * @param second second EmergencyNumber to compare
     * @return a merged EmergencyNumber or null if they are not the same EmergencyNumber
     *
     * @hide
     */
    public static EmergencyNumber mergeSameEmergencyNumbers(@NonNull EmergencyNumber first,
                                                            @NonNull EmergencyNumber second) {
        if (areSameEmergencyNumbers(first, second)) {
            return new EmergencyNumber(first.getNumber(), first.getCountryIso(), first.getMnc(),
                    first.getEmergencyServiceCategoryBitmask(),
                    first.getEmergencyUrns(),
                    first.getEmergencyNumberSourceBitmask()
                            | second.getEmergencyNumberSourceBitmask(),
                    first.getEmergencyCallRouting());
        }
        return null;
    }

    /**
     * Validate Emergency Number address that only contains the dialable character
     * {@link PhoneNumberUtils#isDialable(char)}
     *
     * @hide
     */
    public static boolean validateEmergencyNumberAddress(String address) {
        if (address == null) {
            return false;
        }
        for (char c : address.toCharArray()) {
            if (!PhoneNumberUtils.isDialable(c)) {
                return false;
            }
        }
        return true;
    }
}
