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

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
import android.telephony.UiccAccessRule;
import android.text.TextUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * Information about an embedded profile (subscription) on an eUICC.
 *
 * @hide
 */
@SystemApi
public final class EuiccProfileInfo implements Parcelable {

    /** Profile policy rules (bit mask) */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "POLICY_RULE_" }, value = {
            POLICY_RULE_DO_NOT_DISABLE,
            POLICY_RULE_DO_NOT_DELETE,
            POLICY_RULE_DELETE_AFTER_DISABLING
    })
    /** @hide */
    public @interface PolicyRule {}
    /** Once this profile is enabled, it cannot be disabled. */
    public static final int POLICY_RULE_DO_NOT_DISABLE = 1;
    /** This profile cannot be deleted. */
    public static final int POLICY_RULE_DO_NOT_DELETE = 1 << 1;
    /** This profile should be deleted after being disabled. */
    public static final int POLICY_RULE_DELETE_AFTER_DISABLING = 1 << 2;

    /** Class of the profile */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "PROFILE_CLASS_" }, value = {
            PROFILE_CLASS_TESTING,
            PROFILE_CLASS_PROVISIONING,
            PROFILE_CLASS_OPERATIONAL,
            PROFILE_CLASS_UNSET
    })
    /** @hide */
    public @interface ProfileClass {}
    /** Testing profiles */
    public static final int PROFILE_CLASS_TESTING = 0;
    /** Provisioning profiles which are pre-loaded on eUICC */
    public static final int PROFILE_CLASS_PROVISIONING = 1;
    /** Operational profiles which can be pre-loaded or downloaded */
    public static final int PROFILE_CLASS_OPERATIONAL = 2;
    /**
     * Profile class not set.
     * @hide
     */
    public static final int PROFILE_CLASS_UNSET = -1;

    /** State of the profile */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "PROFILE_STATE_" }, value = {
            PROFILE_STATE_DISABLED,
            PROFILE_STATE_ENABLED,
            PROFILE_STATE_UNSET
    })
    /** @hide */
    public @interface ProfileState {}
    /** Disabled profiles */
    public static final int PROFILE_STATE_DISABLED = 0;
    /** Enabled profile */
    public static final int PROFILE_STATE_ENABLED = 1;
    /**
     * Profile state not set.
     * @hide
     */
    public static final int PROFILE_STATE_UNSET = -1;

    /** The iccid of the subscription. */
    private final String mIccid;

    /** An optional nickname for the subscription. */
    private final @Nullable String mNickname;

    /** The service provider name for the subscription. */
    private final String mServiceProviderName;

    /** The profile name for the subscription. */
    private final String mProfileName;

    /** Profile class for the subscription. */
    @ProfileClass private final int mProfileClass;

    /** The profile state of the subscription. */
    @ProfileState private final int mState;

    /** The operator Id of the subscription. */
    private final CarrierIdentifier mCarrierIdentifier;

    /** The policy rules of the subscription. */
    @PolicyRule private final int mPolicyRules;

    /**
     * Optional access rules defining which apps can manage this subscription. If unset, only the
     * platform can manage it.
     */
    private final @Nullable UiccAccessRule[] mAccessRules;

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

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

    // TODO(b/70292228): Remove this method when LPA can be updated.
    /**
     * @hide
     * @deprecated - Do not use.
     */
    @Deprecated
    @UnsupportedAppUsage
    public EuiccProfileInfo(String iccid, @Nullable UiccAccessRule[] accessRules,
            @Nullable String nickname) {
        if (!TextUtils.isDigitsOnly(iccid)) {
            throw new IllegalArgumentException("iccid contains invalid characters: " + iccid);
        }
        this.mIccid = iccid;
        this.mAccessRules = accessRules;
        this.mNickname = nickname;

        this.mServiceProviderName = null;
        this.mProfileName = null;
        this.mProfileClass = PROFILE_CLASS_UNSET;
        this.mState = PROFILE_STATE_UNSET;
        this.mCarrierIdentifier = null;
        this.mPolicyRules = 0;
    }

    private EuiccProfileInfo(Parcel in) {
        mIccid = in.readString();
        mNickname = in.readString();
        mServiceProviderName = in.readString();
        mProfileName = in.readString();
        mProfileClass = in.readInt();
        mState = in.readInt();
        byte exist = in.readByte();
        if (exist == (byte) 1) {
            mCarrierIdentifier = CarrierIdentifier.CREATOR.createFromParcel(in);
        } else {
            mCarrierIdentifier = null;
        }
        mPolicyRules = in.readInt();
        mAccessRules = in.createTypedArray(UiccAccessRule.CREATOR);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mIccid);
        dest.writeString(mNickname);
        dest.writeString(mServiceProviderName);
        dest.writeString(mProfileName);
        dest.writeInt(mProfileClass);
        dest.writeInt(mState);
        if (mCarrierIdentifier != null) {
            dest.writeByte((byte) 1);
            mCarrierIdentifier.writeToParcel(dest, flags);
        } else {
            dest.writeByte((byte) 0);
        }
        dest.writeInt(mPolicyRules);
        dest.writeTypedArray(mAccessRules, flags);
    }

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

    /** The builder to build a new {@link EuiccProfileInfo} instance. */
    public static final class Builder {
        private String mIccid;
        private List<UiccAccessRule> mAccessRules;
        private String mNickname;
        private String mServiceProviderName;
        private String mProfileName;
        @ProfileClass private int mProfileClass;
        @ProfileState private int mState;
        private CarrierIdentifier mCarrierIdentifier;
        @PolicyRule private int mPolicyRules;

        public Builder(String value) {
            if (!TextUtils.isDigitsOnly(value)) {
                throw new IllegalArgumentException("iccid contains invalid characters: " + value);
            }
            mIccid = value;
        }

        public Builder(EuiccProfileInfo baseProfile) {
            mIccid = baseProfile.mIccid;
            mNickname = baseProfile.mNickname;
            mServiceProviderName = baseProfile.mServiceProviderName;
            mProfileName = baseProfile.mProfileName;
            mProfileClass = baseProfile.mProfileClass;
            mState = baseProfile.mState;
            mCarrierIdentifier = baseProfile.mCarrierIdentifier;
            mPolicyRules = baseProfile.mPolicyRules;
            mAccessRules = Arrays.asList(baseProfile.mAccessRules);
        }

        /** Builds the profile instance. */
        public EuiccProfileInfo build() {
            if (mIccid == null) {
                throw new IllegalStateException("ICCID must be set for a profile.");
            }
            return new EuiccProfileInfo(
                    mIccid,
                    mNickname,
                    mServiceProviderName,
                    mProfileName,
                    mProfileClass,
                    mState,
                    mCarrierIdentifier,
                    mPolicyRules,
                    mAccessRules);
        }

        /** Sets the iccId of the subscription. */
        public Builder setIccid(String value) {
            if (!TextUtils.isDigitsOnly(value)) {
                throw new IllegalArgumentException("iccid contains invalid characters: " + value);
            }
            mIccid = value;
            return this;
        }

        /** Sets the nickname of the subscription. */
        public Builder setNickname(String value) {
            mNickname = value;
            return this;
        }

        /** Sets the service provider name of the subscription. */
        public Builder setServiceProviderName(String value) {
            mServiceProviderName = value;
            return this;
        }

        /** Sets the profile name of the subscription. */
        public Builder setProfileName(String value) {
            mProfileName = value;
            return this;
        }

        /** Sets the profile class of the subscription. */
        public Builder setProfileClass(@ProfileClass int value) {
            mProfileClass = value;
            return this;
        }

        /** Sets the state of the subscription. */
        public Builder setState(@ProfileState int value) {
            mState = value;
            return this;
        }

        /** Sets the carrier identifier of the subscription. */
        public Builder setCarrierIdentifier(CarrierIdentifier value) {
            mCarrierIdentifier = value;
            return this;
        }

        /** Sets the policy rules of the subscription. */
        public Builder setPolicyRules(@PolicyRule int value) {
            mPolicyRules = value;
            return this;
        }

        /** Sets the access rules of the subscription. */
        public Builder setUiccAccessRule(@Nullable List<UiccAccessRule> value) {
            mAccessRules = value;
            return this;
        }
    }

    private EuiccProfileInfo(
            String iccid,
            @Nullable String nickname,
            String serviceProviderName,
            String profileName,
            @ProfileClass int profileClass,
            @ProfileState int state,
            CarrierIdentifier carrierIdentifier,
            @PolicyRule int policyRules,
            @Nullable List<UiccAccessRule> accessRules) {
        this.mIccid = iccid;
        this.mNickname = nickname;
        this.mServiceProviderName = serviceProviderName;
        this.mProfileName = profileName;
        this.mProfileClass = profileClass;
        this.mState = state;
        this.mCarrierIdentifier = carrierIdentifier;
        this.mPolicyRules = policyRules;
        if (accessRules != null && accessRules.size() > 0) {
            this.mAccessRules = accessRules.toArray(new UiccAccessRule[accessRules.size()]);
        } else {
            this.mAccessRules = null;
        }
    }

    /** Gets the ICCID string. */
    public String getIccid() {
        return mIccid;
    }

    /** Gets the access rules. */
    @Nullable
    public List<UiccAccessRule> getUiccAccessRules() {
        if (mAccessRules == null) return null;
        return Arrays.asList(mAccessRules);
    }

    /** Gets the nickname. */
    @Nullable
    public String getNickname() {
        return mNickname;
    }

    /** Gets the service provider name. */
    public String getServiceProviderName() {
        return mServiceProviderName;
    }

    /** Gets the profile name. */
    public String getProfileName() {
        return mProfileName;
    }

    /** Gets the profile class. */
    @ProfileClass
    public int getProfileClass() {
        return mProfileClass;
    }

    /** Gets the state of the subscription. */
    @ProfileState
    public int getState() {
        return mState;
    }

    /** Gets the carrier identifier. */
    public CarrierIdentifier getCarrierIdentifier() {
        return mCarrierIdentifier;
    }

    /** Gets the policy rules. */
    @PolicyRule
    public int getPolicyRules() {
        return mPolicyRules;
    }

    /** Returns whether any policy rule exists. */
    public boolean hasPolicyRules() {
        return mPolicyRules != 0;
    }

    /** Checks whether a certain policy rule exists. */
    public boolean hasPolicyRule(@PolicyRule int policy) {
        return (mPolicyRules & policy) != 0;
    }

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

        EuiccProfileInfo that = (EuiccProfileInfo) obj;
        return Objects.equals(mIccid, that.mIccid)
                && Objects.equals(mNickname, that.mNickname)
                && Objects.equals(mServiceProviderName, that.mServiceProviderName)
                && Objects.equals(mProfileName, that.mProfileName)
                && mProfileClass == that.mProfileClass
                && mState == that.mState
                && Objects.equals(mCarrierIdentifier, that.mCarrierIdentifier)
                && mPolicyRules == that.mPolicyRules
                && Arrays.equals(mAccessRules, that.mAccessRules);
    }

    @Override
    public int hashCode() {
        int result = 1;
        result = 31 * result + Objects.hashCode(mIccid);
        result = 31 * result + Objects.hashCode(mNickname);
        result = 31 * result + Objects.hashCode(mServiceProviderName);
        result = 31 * result + Objects.hashCode(mProfileName);
        result = 31 * result + mProfileClass;
        result = 31 * result + mState;
        result = 31 * result + Objects.hashCode(mCarrierIdentifier);
        result = 31 * result + mPolicyRules;
        result = 31 * result + Arrays.hashCode(mAccessRules);
        return result;
    }

    @NonNull
    @Override
    public String toString() {
        return "EuiccProfileInfo (nickname="
                + mNickname
                + ", serviceProviderName="
                + mServiceProviderName
                + ", profileName="
                + mProfileName
                + ", profileClass="
                + mProfileClass
                + ", state="
                + mState
                + ", CarrierIdentifier="
                + mCarrierIdentifier
                + ", policyRules="
                + mPolicyRules
                + ", accessRules="
                + Arrays.toString(mAccessRules)
                + ")";
    }
}
