/*
 * Copyright (C) 2016 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.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @hide
 */
@SystemApi
public class ParcelableCallAnalytics implements Parcelable {
    /** {@hide} */
    public static final class VideoEvent implements Parcelable {
        public static final int SEND_LOCAL_SESSION_MODIFY_REQUEST = 0;
        public static final int SEND_LOCAL_SESSION_MODIFY_RESPONSE = 1;
        public static final int RECEIVE_REMOTE_SESSION_MODIFY_REQUEST = 2;
        public static final int RECEIVE_REMOTE_SESSION_MODIFY_RESPONSE = 3;

        public static final @android.annotation.NonNull Parcelable.Creator<VideoEvent> CREATOR =
                new Parcelable.Creator<VideoEvent> () {

                    @Override
                    public VideoEvent createFromParcel(Parcel in) {
                        return new VideoEvent(in);
                    }

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

        private int mEventName;
        private long mTimeSinceLastEvent;
        private int mVideoState;

        public VideoEvent(int eventName, long timeSinceLastEvent, int videoState) {
            mEventName = eventName;
            mTimeSinceLastEvent = timeSinceLastEvent;
            mVideoState = videoState;
        }

        VideoEvent(Parcel in) {
            mEventName = in.readInt();
            mTimeSinceLastEvent = in.readLong();
            mVideoState = in.readInt();
        }

        public int getEventName() {
            return mEventName;
        }

        public long getTimeSinceLastEvent() {
            return mTimeSinceLastEvent;
        }

        public int getVideoState() {
            return mVideoState;
        }

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

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(mEventName);
            out.writeLong(mTimeSinceLastEvent);
            out.writeInt(mVideoState);
        }
    }

    public static final class AnalyticsEvent implements Parcelable {
        public static final int SET_SELECT_PHONE_ACCOUNT = 0;
        public static final int SET_ACTIVE = 1;
        public static final int SET_DISCONNECTED = 2;
        public static final int START_CONNECTION = 3;
        public static final int SET_DIALING = 4;
        public static final int BIND_CS = 5;
        public static final int CS_BOUND = 6;
        public static final int REQUEST_ACCEPT = 7;
        public static final int REQUEST_REJECT = 8;

        public static final int SCREENING_SENT = 100;
        public static final int SCREENING_COMPLETED = 101;
        public static final int DIRECT_TO_VM_INITIATED = 102;
        public static final int DIRECT_TO_VM_FINISHED = 103;
        public static final int BLOCK_CHECK_INITIATED = 104;
        public static final int BLOCK_CHECK_FINISHED = 105;
        public static final int FILTERING_INITIATED = 106;
        public static final int FILTERING_COMPLETED = 107;
        public static final int FILTERING_TIMED_OUT = 108;

        public static final int SKIP_RINGING = 200;
        public static final int SILENCE = 201;
        public static final int MUTE = 202;
        public static final int UNMUTE = 203;
        public static final int AUDIO_ROUTE_BT = 204;
        public static final int AUDIO_ROUTE_EARPIECE = 205;
        public static final int AUDIO_ROUTE_HEADSET = 206;
        public static final int AUDIO_ROUTE_SPEAKER = 207;

        public static final int CONFERENCE_WITH = 300;
        public static final int SPLIT_CONFERENCE = 301;
        public static final int SET_PARENT = 302;

        public static final int REQUEST_HOLD = 400;
        public static final int REQUEST_UNHOLD = 401;
        public static final int REMOTELY_HELD = 402;
        public static final int REMOTELY_UNHELD = 403;
        public static final int SET_HOLD = 404;
        public static final int SWAP = 405;

        public static final int REQUEST_PULL = 500;


        public static final @android.annotation.NonNull Parcelable.Creator<AnalyticsEvent> CREATOR =
                new Parcelable.Creator<AnalyticsEvent> () {

                    @Override
                    public AnalyticsEvent createFromParcel(Parcel in) {
                        return new AnalyticsEvent(in);
                    }

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

        private int mEventName;
        private long mTimeSinceLastEvent;

        public AnalyticsEvent(int eventName, long timestamp) {
            mEventName = eventName;
            mTimeSinceLastEvent = timestamp;
        }

        AnalyticsEvent(Parcel in) {
            mEventName = in.readInt();
            mTimeSinceLastEvent = in.readLong();
        }

        public int getEventName() {
            return mEventName;
        }

        public long getTimeSinceLastEvent() {
            return mTimeSinceLastEvent;
        }

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

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(mEventName);
            out.writeLong(mTimeSinceLastEvent);
        }
    }

    public static final class EventTiming implements Parcelable {
        public static final int ACCEPT_TIMING = 0;
        public static final int REJECT_TIMING = 1;
        public static final int DISCONNECT_TIMING = 2;
        public static final int HOLD_TIMING = 3;
        public static final int UNHOLD_TIMING = 4;
        public static final int OUTGOING_TIME_TO_DIALING_TIMING = 5;
        public static final int BIND_CS_TIMING = 6;
        public static final int SCREENING_COMPLETED_TIMING = 7;
        public static final int DIRECT_TO_VM_FINISHED_TIMING = 8;
        public static final int BLOCK_CHECK_FINISHED_TIMING = 9;
        public static final int FILTERING_COMPLETED_TIMING = 10;
        public static final int FILTERING_TIMED_OUT_TIMING = 11;
        /** {@hide} */
        public static final int START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING = 12;

        public static final int INVALID = 999999;

        public static final @android.annotation.NonNull Parcelable.Creator<EventTiming> CREATOR =
                new Parcelable.Creator<EventTiming> () {

                    @Override
                    public EventTiming createFromParcel(Parcel in) {
                        return new EventTiming(in);
                    }

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

        private int mName;
        private long mTime;

        public EventTiming(int name, long time) {
            this.mName = name;
            this.mTime = time;
        }

        private EventTiming(Parcel in) {
            mName = in.readInt();
            mTime = in.readLong();
        }

        public int getName() {
            return mName;
        }

        public long getTime() {
            return mTime;
        }

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

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(mName);
            out.writeLong(mTime);
        }
    }

    public static final int CALLTYPE_UNKNOWN = 0;
    public static final int CALLTYPE_INCOMING = 1;
    public static final int CALLTYPE_OUTGOING = 2;

    // Constants for call technology
    public static final int CDMA_PHONE = 0x1;
    public static final int GSM_PHONE = 0x2;
    public static final int IMS_PHONE = 0x4;
    public static final int SIP_PHONE = 0x8;
    public static final int THIRD_PARTY_PHONE = 0x10;

    public static final long MILLIS_IN_5_MINUTES = 1000 * 60 * 5;
    public static final long MILLIS_IN_1_SECOND = 1000;

    public static final int STILL_CONNECTED = -1;

    public static final @android.annotation.NonNull Parcelable.Creator<ParcelableCallAnalytics> CREATOR =
            new Parcelable.Creator<ParcelableCallAnalytics> () {

                @Override
                public ParcelableCallAnalytics createFromParcel(Parcel in) {
                    return new ParcelableCallAnalytics(in);
                }

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

    // The start time of the call in milliseconds since Jan. 1, 1970, rounded to the nearest
    // 5 minute increment.
    private final long startTimeMillis;

    // The duration of the call, in milliseconds.
    private final long callDurationMillis;

    // ONE OF calltype_unknown, calltype_incoming, or calltype_outgoing
    private final int callType;

    // true if the call came in while another call was in progress or if the user dialed this call
    // while in the middle of another call.
    private final boolean isAdditionalCall;

    // true if the call was interrupted by an incoming or outgoing call.
    private final boolean isInterrupted;

    // bitmask denoting which technologies a call used.
    private final int callTechnologies;

    // Any of the DisconnectCause codes, or STILL_CONNECTED.
    private final int callTerminationCode;

    // Whether the call is an emergency call
    private final boolean isEmergencyCall;

    // The package name of the connection service that this call used.
    private final String connectionService;

    // Whether the call object was created from an existing connection.
    private final boolean isCreatedFromExistingConnection;

    // A list of events that are associated with this call
    private final List<AnalyticsEvent> analyticsEvents;

    // A map from event-pair names to their durations.
    private final List<EventTiming> eventTimings;

    // Whether the call has ever been a video call.
    private boolean isVideoCall = false;

    // A list of video events that have occurred.
    private List<VideoEvent> videoEvents;

    // The source where user initiated this call. ONE OF the CALL_SOURCE_* constants.
    private int callSource = TelecomManager.CALL_SOURCE_UNSPECIFIED;

    public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
            boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
            int callTerminationCode, boolean isEmergencyCall, String connectionService,
            boolean isCreatedFromExistingConnection, List<AnalyticsEvent> analyticsEvents,
            List<EventTiming> eventTimings) {
        this.startTimeMillis = startTimeMillis;
        this.callDurationMillis = callDurationMillis;
        this.callType = callType;
        this.isAdditionalCall = isAdditionalCall;
        this.isInterrupted = isInterrupted;
        this.callTechnologies = callTechnologies;
        this.callTerminationCode = callTerminationCode;
        this.isEmergencyCall = isEmergencyCall;
        this.connectionService = connectionService;
        this.isCreatedFromExistingConnection = isCreatedFromExistingConnection;
        this.analyticsEvents = analyticsEvents;
        this.eventTimings = eventTimings;
    }

    public ParcelableCallAnalytics(Parcel in) {
        startTimeMillis = in.readLong();
        callDurationMillis = in.readLong();
        callType = in.readInt();
        isAdditionalCall = readByteAsBoolean(in);
        isInterrupted = readByteAsBoolean(in);
        callTechnologies = in.readInt();
        callTerminationCode = in.readInt();
        isEmergencyCall = readByteAsBoolean(in);
        connectionService = in.readString();
        isCreatedFromExistingConnection = readByteAsBoolean(in);
        analyticsEvents = new ArrayList<>();
        in.readTypedList(analyticsEvents, AnalyticsEvent.CREATOR);
        eventTimings = new ArrayList<>();
        in.readTypedList(eventTimings, EventTiming.CREATOR);
        isVideoCall = readByteAsBoolean(in);
        videoEvents = new LinkedList<>();
        in.readTypedList(videoEvents, VideoEvent.CREATOR);
        callSource = in.readInt();
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeLong(startTimeMillis);
        out.writeLong(callDurationMillis);
        out.writeInt(callType);
        writeBooleanAsByte(out, isAdditionalCall);
        writeBooleanAsByte(out, isInterrupted);
        out.writeInt(callTechnologies);
        out.writeInt(callTerminationCode);
        writeBooleanAsByte(out, isEmergencyCall);
        out.writeString(connectionService);
        writeBooleanAsByte(out, isCreatedFromExistingConnection);
        out.writeTypedList(analyticsEvents);
        out.writeTypedList(eventTimings);
        writeBooleanAsByte(out, isVideoCall);
        out.writeTypedList(videoEvents);
        out.writeInt(callSource);
    }

    /** {@hide} */
    public void setIsVideoCall(boolean isVideoCall) {
        this.isVideoCall = isVideoCall;
    }

    /** {@hide} */
    public void setVideoEvents(List<VideoEvent> videoEvents) {
        this.videoEvents = videoEvents;
    }

    /** {@hide} */
    public void setCallSource(int callSource) {
        this.callSource = callSource;
    }

    public long getStartTimeMillis() {
        return startTimeMillis;
    }

    public long getCallDurationMillis() {
        return callDurationMillis;
    }

    public int getCallType() {
        return callType;
    }

    public boolean isAdditionalCall() {
        return isAdditionalCall;
    }

    public boolean isInterrupted() {
        return isInterrupted;
    }

    public int getCallTechnologies() {
        return callTechnologies;
    }

    public int getCallTerminationCode() {
        return callTerminationCode;
    }

    public boolean isEmergencyCall() {
        return isEmergencyCall;
    }

    public String getConnectionService() {
        return connectionService;
    }

    public boolean isCreatedFromExistingConnection() {
        return isCreatedFromExistingConnection;
    }

    public List<AnalyticsEvent> analyticsEvents() {
        return analyticsEvents;
    }

    public List<EventTiming> getEventTimings() {
        return eventTimings;
    }

    /** {@hide} */
    public boolean isVideoCall() {
        return isVideoCall;
    }

    /** {@hide} */
    public List<VideoEvent> getVideoEvents() {
        return videoEvents;
    }

    /** {@hide} */
    public int getCallSource() {
        return callSource;
    }

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

    private static void writeBooleanAsByte(Parcel out, boolean b) {
        out.writeByte((byte) (b ? 1 : 0));
    }

    private static boolean readByteAsBoolean(Parcel in) {
        return (in.readByte() == 1);
    }
}
