/**
 * 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()}
     * @hide
     *
     * TODO: expose this to public API
     */
    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;
    }

    /**
     * Get the carrier id {@link TelephonyManager#getSimCarrierId() }
     * @hide
     */
    public int getCarrierId() {
        return mCarrierId;
    }

    /**
     * Get the precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()}
     * @hide
     */
    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;
    }
}
