/*
 * 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.compat.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)
                + ")";
    }
}
