/*
 * Copyright 2014, 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.telecom;

import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.telecom.Call.Details.CallDirection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.android.internal.telecom.IVideoProvider;

/**
 * Information about a call that is used between InCallService and Telecom.
 * @hide
 */
public final class ParcelableCall implements Parcelable {
    private final String mId;
    private final int mState;
    private final DisconnectCause mDisconnectCause;
    private final List<String> mCannedSmsResponses;
    private final int mCapabilities;
    private final int mProperties;
    private final int mSupportedAudioRoutes;
    private final long mConnectTimeMillis;
    private final Uri mHandle;
    private final int mHandlePresentation;
    private final String mCallerDisplayName;
    private final int mCallerDisplayNamePresentation;
    private final GatewayInfo mGatewayInfo;
    private final PhoneAccountHandle mAccountHandle;
    private final boolean mIsVideoCallProviderChanged;
    private final IVideoProvider mVideoCallProvider;
    private VideoCallImpl mVideoCall;
    private final boolean mIsRttCallChanged;
    private final ParcelableRttCall mRttCall;
    private final String mParentCallId;
    private final List<String> mChildCallIds;
    private final StatusHints mStatusHints;
    private final int mVideoState;
    private final List<String> mConferenceableCallIds;
    private final Bundle mIntentExtras;
    private final Bundle mExtras;
    private final long mCreationTimeMillis;
    private final CallIdentification mCallIdentification;
    private final int mCallDirection;

    public ParcelableCall(
            String id,
            int state,
            DisconnectCause disconnectCause,
            List<String> cannedSmsResponses,
            int capabilities,
            int properties,
            int supportedAudioRoutes,
            long connectTimeMillis,
            Uri handle,
            int handlePresentation,
            String callerDisplayName,
            int callerDisplayNamePresentation,
            GatewayInfo gatewayInfo,
            PhoneAccountHandle accountHandle,
            boolean isVideoCallProviderChanged,
            IVideoProvider videoCallProvider,
            boolean isRttCallChanged,
            ParcelableRttCall rttCall,
            String parentCallId,
            List<String> childCallIds,
            StatusHints statusHints,
            int videoState,
            List<String> conferenceableCallIds,
            Bundle intentExtras,
            Bundle extras,
            long creationTimeMillis,
            CallIdentification callIdentification,
            int callDirection) {
        mId = id;
        mState = state;
        mDisconnectCause = disconnectCause;
        mCannedSmsResponses = cannedSmsResponses;
        mCapabilities = capabilities;
        mProperties = properties;
        mSupportedAudioRoutes = supportedAudioRoutes;
        mConnectTimeMillis = connectTimeMillis;
        mHandle = handle;
        mHandlePresentation = handlePresentation;
        mCallerDisplayName = callerDisplayName;
        mCallerDisplayNamePresentation = callerDisplayNamePresentation;
        mGatewayInfo = gatewayInfo;
        mAccountHandle = accountHandle;
        mIsVideoCallProviderChanged = isVideoCallProviderChanged;
        mVideoCallProvider = videoCallProvider;
        mIsRttCallChanged = isRttCallChanged;
        mRttCall = rttCall;
        mParentCallId = parentCallId;
        mChildCallIds = childCallIds;
        mStatusHints = statusHints;
        mVideoState = videoState;
        mConferenceableCallIds = Collections.unmodifiableList(conferenceableCallIds);
        mIntentExtras = intentExtras;
        mExtras = extras;
        mCreationTimeMillis = creationTimeMillis;
        mCallIdentification = callIdentification;
        mCallDirection = callDirection;
    }

    /** The unique ID of the call. */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public String getId() {
        return mId;
    }

    /** The current state of the call. */
    public int getState() {
        return mState;
    }

    /**
     * Reason for disconnection, as described by {@link android.telecomm.DisconnectCause}. Valid
     * when call state is {@link CallState#DISCONNECTED}.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public DisconnectCause getDisconnectCause() {
        return mDisconnectCause;
    }

    /**
     * The set of possible text message responses when this call is incoming.
     */
    public List<String> getCannedSmsResponses() {
        return mCannedSmsResponses;
    }

    // Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
    public int getCapabilities() {
        return mCapabilities;
    }

    /** Bitmask of properties of the call. */
    public int getProperties() { return mProperties; }

    /** Bitmask of supported routes of the call */
    public int getSupportedAudioRoutes() {
        return mSupportedAudioRoutes;
    }

    /** The time that the call switched to the active state. */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public long getConnectTimeMillis() {
        return mConnectTimeMillis;
    }

    /** The endpoint to which the call is connected. */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public Uri getHandle() {
        return mHandle;
    }

    /**
     * The presentation requirements for the handle. See {@link TelecomManager} for valid values.
     */
    public int getHandlePresentation() {
        return mHandlePresentation;
    }

    /** The endpoint to which the call is connected. */
    public String getCallerDisplayName() {
        return mCallerDisplayName;
    }

    /**
     * The presentation requirements for the caller display name.
     * See {@link TelecomManager} for valid values.
     */
    public int getCallerDisplayNamePresentation() {
        return mCallerDisplayNamePresentation;
    }

    /** Gateway information for the call. */
    public GatewayInfo getGatewayInfo() {
        return mGatewayInfo;
    }

    /** PhoneAccountHandle information for the call. */
    public PhoneAccountHandle getAccountHandle() {
        return mAccountHandle;
    }

    /**
     * Returns an object for remotely communicating through the video call provider's binder.
     *
     * @param callingPackageName the package name of the calling InCallService.
     * @param targetSdkVersion the target SDK version of the calling InCallService.
     * @return The video call.
     */
    public VideoCallImpl getVideoCallImpl(String callingPackageName, int targetSdkVersion) {
        if (mVideoCall == null && mVideoCallProvider != null) {
            try {
                mVideoCall = new VideoCallImpl(mVideoCallProvider, callingPackageName,
                        targetSdkVersion);
            } catch (RemoteException ignored) {
                // Ignore RemoteException.
            }
        }

        return mVideoCall;
    }

    public boolean getIsRttCallChanged() {
        return mIsRttCallChanged;
    }

    /**
     * RTT communication channel information
     * @return The ParcelableRttCall
     */
    public ParcelableRttCall getParcelableRttCall() {
        return mRttCall;
    }

    /**
     * The conference call to which this call is conferenced. Null if not conferenced.
     */
    public String getParentCallId() {
        return mParentCallId;
    }

    /**
     * The child call-IDs if this call is a conference call. Returns an empty list if this is not
     * a conference call or if the conference call contains no children.
     */
    public List<String> getChildCallIds() {
        return mChildCallIds;
    }

    public List<String> getConferenceableCallIds() {
        return mConferenceableCallIds;
    }

    /**
     * The status label and icon.
     *
     * @return Status hints.
     */
    public StatusHints getStatusHints() {
        return mStatusHints;
    }

    /**
     * The video state.
     * @return The video state of the call.
     */
    public int getVideoState() {
        return mVideoState;
    }

    /**
     * Any extras associated with this call.
     *
     * @return a bundle of extras
     */
    public Bundle getExtras() {
        return mExtras;
    }

    /**
     * Extras passed in as part of the original call intent.
     *
     * @return The intent extras.
     */
    public Bundle getIntentExtras() {
        return mIntentExtras;
    }

    /**
     * Indicates to the receiver of the {@link ParcelableCall} whether a change has occurred in the
     * {@link android.telecom.InCallService.VideoCall} associated with this call.  Since
     * {@link #getVideoCall()} creates a new {@link VideoCallImpl}, it is useful to know whether
     * the provider has changed (which can influence whether it is accessed).
     *
     * @return {@code true} if the video call changed, {@code false} otherwise.
     */
    public boolean isVideoCallProviderChanged() {
        return mIsVideoCallProviderChanged;
    }

    /**
     * @return The time the call was created, in milliseconds since the epoch.
     */
    public long getCreationTimeMillis() {
        return mCreationTimeMillis;
    }

    /**
     * Contains call identification information returned by a {@link CallScreeningService}.
     * @return The {@link CallIdentification} for this call, or {@code null} if a
     * {@link CallScreeningService} did not provide information.
     */
    public @Nullable CallIdentification getCallIdentification() {
        return mCallIdentification;
    }

    /**
     * Indicates whether the call is an incoming or outgoing call.
     */
    public @CallDirection int getCallDirection() {
        return mCallDirection;
    }

    /** Responsible for creating ParcelableCall objects for deserialized Parcels. */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public static final @android.annotation.NonNull Parcelable.Creator<ParcelableCall> CREATOR =
            new Parcelable.Creator<ParcelableCall> () {
        @Override
        public ParcelableCall createFromParcel(Parcel source) {
            ClassLoader classLoader = ParcelableCall.class.getClassLoader();
            String id = source.readString();
            int state = source.readInt();
            DisconnectCause disconnectCause = source.readParcelable(classLoader);
            List<String> cannedSmsResponses = new ArrayList<>();
            source.readList(cannedSmsResponses, classLoader);
            int capabilities = source.readInt();
            int properties = source.readInt();
            long connectTimeMillis = source.readLong();
            Uri handle = source.readParcelable(classLoader);
            int handlePresentation = source.readInt();
            String callerDisplayName = source.readString();
            int callerDisplayNamePresentation = source.readInt();
            GatewayInfo gatewayInfo = source.readParcelable(classLoader);
            PhoneAccountHandle accountHandle = source.readParcelable(classLoader);
            boolean isVideoCallProviderChanged = source.readByte() == 1;
            IVideoProvider videoCallProvider =
                    IVideoProvider.Stub.asInterface(source.readStrongBinder());
            String parentCallId = source.readString();
            List<String> childCallIds = new ArrayList<>();
            source.readList(childCallIds, classLoader);
            StatusHints statusHints = source.readParcelable(classLoader);
            int videoState = source.readInt();
            List<String> conferenceableCallIds = new ArrayList<>();
            source.readList(conferenceableCallIds, classLoader);
            Bundle intentExtras = source.readBundle(classLoader);
            Bundle extras = source.readBundle(classLoader);
            int supportedAudioRoutes = source.readInt();
            boolean isRttCallChanged = source.readByte() == 1;
            ParcelableRttCall rttCall = source.readParcelable(classLoader);
            long creationTimeMillis = source.readLong();
            CallIdentification callIdentification = source.readParcelable(classLoader);
            int callDirection = source.readInt();
            return new ParcelableCall(
                    id,
                    state,
                    disconnectCause,
                    cannedSmsResponses,
                    capabilities,
                    properties,
                    supportedAudioRoutes,
                    connectTimeMillis,
                    handle,
                    handlePresentation,
                    callerDisplayName,
                    callerDisplayNamePresentation,
                    gatewayInfo,
                    accountHandle,
                    isVideoCallProviderChanged,
                    videoCallProvider,
                    isRttCallChanged,
                    rttCall,
                    parentCallId,
                    childCallIds,
                    statusHints,
                    videoState,
                    conferenceableCallIds,
                    intentExtras,
                    extras,
                    creationTimeMillis,
                    callIdentification,
                    callDirection);
        }

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

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

    /** Writes ParcelableCall object into a Parcel. */
    @Override
    public void writeToParcel(Parcel destination, int flags) {
        destination.writeString(mId);
        destination.writeInt(mState);
        destination.writeParcelable(mDisconnectCause, 0);
        destination.writeList(mCannedSmsResponses);
        destination.writeInt(mCapabilities);
        destination.writeInt(mProperties);
        destination.writeLong(mConnectTimeMillis);
        destination.writeParcelable(mHandle, 0);
        destination.writeInt(mHandlePresentation);
        destination.writeString(mCallerDisplayName);
        destination.writeInt(mCallerDisplayNamePresentation);
        destination.writeParcelable(mGatewayInfo, 0);
        destination.writeParcelable(mAccountHandle, 0);
        destination.writeByte((byte) (mIsVideoCallProviderChanged ? 1 : 0));
        destination.writeStrongBinder(
                mVideoCallProvider != null ? mVideoCallProvider.asBinder() : null);
        destination.writeString(mParentCallId);
        destination.writeList(mChildCallIds);
        destination.writeParcelable(mStatusHints, 0);
        destination.writeInt(mVideoState);
        destination.writeList(mConferenceableCallIds);
        destination.writeBundle(mIntentExtras);
        destination.writeBundle(mExtras);
        destination.writeInt(mSupportedAudioRoutes);
        destination.writeByte((byte) (mIsRttCallChanged ? 1 : 0));
        destination.writeParcelable(mRttCall, 0);
        destination.writeLong(mCreationTimeMillis);
        destination.writeParcelable(mCallIdentification, 0);
        destination.writeInt(mCallDirection);
    }

    @Override
    public String toString() {
        return String.format("[%s, parent:%s, children:%s]", mId, mParentCallId, mChildCallIds);
    }
}
