/**
 * 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.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(String mcc, 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;
    }
}
