/*
 * Copyright (C) 2018 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.telephony.ims;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Provides the call forward information for the supplementary service configuration.
 *
 * @hide
 */
@SystemApi
public final class ImsCallForwardInfo implements Parcelable {

    /**
     * CDIV (Communication Diversion, 3GPP TS 24.604) call forwarding reason for unconditional call
     * forwarding. See TC 27.007
     */
    public static final int CDIV_CF_REASON_UNCONDITIONAL = 0;

    /**
     * CDIV (Communication Diversion, 3GPP TS 24.604) call forwarding reason for call forwarding
     * when the user is busy.
     */
    public static final int CDIV_CF_REASON_BUSY = 1;

    /**
     * CDIV (Communication Diversion, 3GPP TS 24.604) call forwarding reason for call forwarding
     * when there is no reply from the user.
     */
    public static final int CDIV_CF_REASON_NO_REPLY = 2;

    /**
     * CDIV (Communication Diversion, 3GPP TS 24.604) call forwarding reason for call forwarding
     * when the user is not reachable.
     */
    public static final int CDIV_CF_REASON_NOT_REACHABLE = 3;

    /**
     * CDIV (Communication Diversion, 3GPP TS 24.604) call forwarding reason for setting all call
     * forwarding reasons simultaneously (i.e. unconditional, busy, no reply, and not reachable).
     */
    public static final int CDIV_CF_REASON_ALL = 4;

    /**
     * CDIV (Communication Diversion, 3GPP TS 24.604) call forwarding reason for setting all
     * conditional call forwarding reasons simultaneously (i.e. if busy, if no reply, and if not
     * reachable).
     */
    public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5;

    /**
     * CDIV (Communication Diversion) IMS only call forwarding reason for call forwarding when the
     * user is not logged in.
     */
    public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6;

    /**@hide*/
    @IntDef(prefix = {"CDIV_CF_REASON_"}, value = {
            CDIV_CF_REASON_UNCONDITIONAL,
            CDIV_CF_REASON_BUSY,
            CDIV_CF_REASON_NO_REPLY,
            CDIV_CF_REASON_NOT_REACHABLE,
            CDIV_CF_REASON_ALL,
            CDIV_CF_REASON_ALL_CONDITIONAL,
            CDIV_CF_REASON_NOT_LOGGED_IN})
    @Retention(RetentionPolicy.SOURCE)
    public @interface CallForwardReasons{}

    /**
     * Call forwarding is not active for any service class.
     */
    public static final int STATUS_NOT_ACTIVE = 0;

    /**
     * Call forwarding is active for one or more service classes.
     */
    public static final int STATUS_ACTIVE = 1;

    /**@hide*/
    @IntDef(prefix = {"STATUS_"}, value = {
            STATUS_NOT_ACTIVE,
            STATUS_ACTIVE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface CallForwardStatus{}

    /**
     * The address defined in {@link #getNumber()} is in an unknown format.
     *
     * See TS 27.007, section 7.11 for more information.
     */
    public static final int TYPE_OF_ADDRESS_UNKNOWN = 0x81;
    /**
     * The address defined in {@link #getNumber()} is in E.164 international format, which includes
     * international access code "+".
     *
     * See TS 27.007, section 7.11 for more information.
     */
    public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 0x91;

    /**@hide*/
    @IntDef(prefix = {"TYPE_OF_ADDRESS_"}, value = {
            TYPE_OF_ADDRESS_INTERNATIONAL,
            TYPE_OF_ADDRESS_UNKNOWN})
    @Retention(RetentionPolicy.SOURCE)
    public @interface TypeOfAddress{}

    /**@hide*/
    @UnsupportedAppUsage
    public @CallForwardReasons int mCondition;
    /** @hide */
    @UnsupportedAppUsage
    public @CallForwardStatus int mStatus;
    /** @hide */
    @UnsupportedAppUsage
    public @TypeOfAddress int mToA;
    /** @hide */
    @UnsupportedAppUsage
    public @ImsSsData.ServiceClassFlags int mServiceClass;
    /** @hide */
    @UnsupportedAppUsage
    public String mNumber;
    /** @hide */
    @UnsupportedAppUsage
    public int mTimeSeconds;

    /** @hide */
    @UnsupportedAppUsage
    public ImsCallForwardInfo() {
    }

    /**
     * IMS Call Forward Information.
     */
    public ImsCallForwardInfo(@CallForwardReasons int reason, @CallForwardStatus int status,
            @TypeOfAddress int toA, @ImsSsData.ServiceClassFlags int serviceClass,
            @NonNull String number, int replyTimerSec) {
        mCondition = reason;
        mStatus = status;
        mToA = toA;
        mServiceClass = serviceClass;
        mNumber = number;
        mTimeSeconds = replyTimerSec;
    }

    /** @hide */
    public ImsCallForwardInfo(Parcel in) {
        readFromParcel(in);
    }

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

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mCondition);
        out.writeInt(mStatus);
        out.writeInt(mToA);
        out.writeString(mNumber);
        out.writeInt(mTimeSeconds);
        out.writeInt(mServiceClass);
    }

    @Override
    public String toString() {
        return super.toString() + ", Condition: " + mCondition
            + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled")
            + ", ToA: " + mToA
            + ", Service Class: " + mServiceClass
            + ", Number=" + mNumber
            + ", Time (seconds): " + mTimeSeconds;
    }

    private void readFromParcel(Parcel in) {
        mCondition = in.readInt();
        mStatus = in.readInt();
        mToA = in.readInt();
        mNumber = in.readString();
        mTimeSeconds = in.readInt();
        mServiceClass = in.readInt();
    }

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

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

    /**
     * @return the condition of call forwarding for the service classes specified.
     */
    public @CallForwardReasons int getCondition() {
        return mCondition;
    }

    /**
     * @return The call forwarding status.
     */
    public @CallForwardStatus int getStatus() {
        return mStatus;
    }

    /**
     * @return the type of address (ToA) for the number.
     * @see #getNumber()
     */
    public @TypeOfAddress int getToA() {
        return mToA;
    }

    /**
     * @return a bitfield containing the service classes that are enabled for call forwarding.
     */
    public @ImsSsData.ServiceClassFlags int getServiceClass() {
        return mServiceClass;
    }

    /**
     * @return the call forwarding number associated with call forwarding, with a number type
     * defined by {@link #getToA()}.
     */
    public String getNumber() {
        return mNumber;
    }

    /**
     * @return the number in seconds to wait before the call is forwarded for call forwarding
     * condition {@link #CDIV_CF_REASON_NO_REPLY}
     */
    public int getTimeSeconds() {
        return mTimeSeconds;
    }
}
