/**
 * Copyright (c) 2015, 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.service.carrier;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.TelephonyManager;

import com.android.internal.telephony.uicc.IccUtils;

import java.util.Objects;

/**
 * Used to pass info to CarrierConfigService implementations so they can decide what values to
 * return. Instead of passing mcc, mnc, gid1, gid2, spn, imsi to locate carrier information,
 * CarrierIdentifier also include carrier id {@link TelephonyManager#getSimCarrierId()},
 * a platform-wide unique identifier for each carrier. CarrierConfigService can directly use
 * carrier id as the key to look up the carrier info.
 */
public class CarrierIdentifier implements Parcelable {

    /** Used to create a {@link CarrierIdentifier} from a {@link Parcel}. */
    public static final Creator<CarrierIdentifier> CREATOR = new Creator<CarrierIdentifier>() {
            @Override
        public CarrierIdentifier createFromParcel(Parcel parcel) {
            return new CarrierIdentifier(parcel);
        }

            @Override
        public CarrierIdentifier[] newArray(int i) {
            return new CarrierIdentifier[i];
        }
    };

    private String mMcc;
    private String mMnc;
    private @Nullable String mSpn;
    private @Nullable String mImsi;
    private @Nullable String mGid1;
    private @Nullable String mGid2;
    private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
    private int mPreciseCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;

    public CarrierIdentifier(String mcc, String mnc, @Nullable String spn, @Nullable String imsi,
            @Nullable String gid1, @Nullable String gid2) {
        this(mcc, mnc, spn, imsi, gid1, gid2, TelephonyManager.UNKNOWN_CARRIER_ID,
                TelephonyManager.UNKNOWN_CARRIER_ID);
    }

    /**
     * @param mcc mobile country code
     * @param mnc mobile network code
     * @param spn service provider name
     * @param imsi International Mobile Subscriber Identity {@link TelephonyManager#getSubscriberId()}
     * @param gid1 group id level 1 {@link TelephonyManager#getGroupIdLevel1()}
     * @param gid2 group id level 2
     * @param carrierid carrier unique identifier {@link TelephonyManager#getSimCarrierId()}, used
     *                  to uniquely identify the carrier and look up the carrier configurations.
     * @param preciseCarrierId precise carrier identifier
     * {@link TelephonyManager#getSimPreciseCarrierId()}
     */
    public CarrierIdentifier(@NonNull String mcc, @NonNull String mnc, @Nullable String spn,
                             @Nullable String imsi, @Nullable String gid1, @Nullable String gid2,
                             int carrierid, int preciseCarrierId) {
        mMcc = mcc;
        mMnc = mnc;
        mSpn = spn;
        mImsi = imsi;
        mGid1 = gid1;
        mGid2 = gid2;
        mCarrierId = carrierid;
        mPreciseCarrierId = preciseCarrierId;
    }

    /**
     * Creates a carrier identifier instance.
     *
     * @param mccMnc A 3-byte array as defined by 3GPP TS 24.008.
     * @param gid1 The group identifier level 1.
     * @param gid2 The group identifier level 2.
     * @throws IllegalArgumentException If the length of {@code mccMnc} is not 3.
     */
    public CarrierIdentifier(byte[] mccMnc, @Nullable String gid1, @Nullable String gid2) {
        if (mccMnc.length != 3) {
            throw new IllegalArgumentException(
                    "MCC & MNC must be set by a 3-byte array: byte[" + mccMnc.length + "]");
        }
        String hex = IccUtils.bytesToHexString(mccMnc);
        mMcc = new String(new char[] {hex.charAt(1), hex.charAt(0), hex.charAt(3)});
        if (hex.charAt(2) == 'F') {
            mMnc = new String(new char[] {hex.charAt(5), hex.charAt(4)});
        } else {
            mMnc = new String(new char[] {hex.charAt(5), hex.charAt(4), hex.charAt(2)});
        }
        mGid1 = gid1;
        mGid2 = gid2;
        mSpn = null;
        mImsi = null;
    }

    /** @hide */
    public CarrierIdentifier(Parcel parcel) {
        readFromParcel(parcel);
    }

    /** Get the mobile country code. */
    public String getMcc() {
        return mMcc;
    }

    /** Get the mobile network code. */
    public String getMnc() {
        return mMnc;
    }

    /** Get the service provider name. */
    @Nullable
    public String getSpn() {
        return mSpn;
    }

    /** Get the international mobile subscriber identity. */
    @Nullable
    public String getImsi() {
        return mImsi;
    }

    /** Get the group identifier level 1. */
    @Nullable
    public String getGid1() {
        return mGid1;
    }

    /** Get the group identifier level 2. */
    @Nullable
    public String getGid2() {
        return mGid2;
    }

    /**
     * Returns the carrier id.
     * @see TelephonyManager#getSimCarrierId()
     */
    public int getCarrierId() {
        return mCarrierId;
    }

    /**
     * Returns the precise carrier id.
     * @see TelephonyManager#getSimPreciseCarrierId()
     */
    public int getPreciseCarrierId() {
        return mPreciseCarrierId;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }

        CarrierIdentifier that = (CarrierIdentifier) obj;
        return Objects.equals(mMcc, that.mMcc)
                && Objects.equals(mMnc, that.mMnc)
                && Objects.equals(mSpn, that.mSpn)
                && Objects.equals(mImsi, that.mImsi)
                && Objects.equals(mGid1, that.mGid1)
                && Objects.equals(mGid2, that.mGid2)
                && Objects.equals(mCarrierId, that.mCarrierId)
                && Objects.equals(mPreciseCarrierId, that.mPreciseCarrierId);
    }

    @Override
    public int hashCode(){
        return Objects.hash(mMcc, mMnc, mSpn, mImsi, mGid1, mGid2, mCarrierId, mPreciseCarrierId);
    }

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

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(mMcc);
        out.writeString(mMnc);
        out.writeString(mSpn);
        out.writeString(mImsi);
        out.writeString(mGid1);
        out.writeString(mGid2);
        out.writeInt(mCarrierId);
        out.writeInt(mPreciseCarrierId);
    }

    @Override
    public String toString() {
      return "CarrierIdentifier{"
              + "mcc=" + mMcc
              + ",mnc=" + mMnc
              + ",spn=" + mSpn
              + ",imsi=" + mImsi
              + ",gid1=" + mGid1
              + ",gid2=" + mGid2
              + ",carrierid=" + mCarrierId
              + ",mPreciseCarrierId=" + mPreciseCarrierId
              + "}";
    }

    /** @hide */
    public void readFromParcel(Parcel in) {
        mMcc = in.readString();
        mMnc = in.readString();
        mSpn = in.readString();
        mImsi = in.readString();
        mGid1 = in.readString();
        mGid2 = in.readString();
        mCarrierId = in.readInt();
        mPreciseCarrierId = in.readInt();
    }

    /** @hide */
    public interface MatchType {
        int ALL = 0;
        int SPN = 1;
        int IMSI_PREFIX = 2;
        int GID1 = 3;
        int GID2 = 4;
    }
}
