/*
 * Copyright (c) 2013 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 com.android.ims;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telecom.Call;
import android.telecom.Connection;

/**
 * Provides the conference information (defined in RFC 4575) for IMS conference call.
 *
 * @hide
 */
public class ImsConferenceState implements Parcelable {
    /**
     * conference-info : user
     */
    // user (String) : Tel or SIP URI
    public static final String USER = "user";
    // user > display text (String)
    public static final String DISPLAY_TEXT = "display-text";
    // user > endpoint (String) : URI or GRUU or Phone number
    public static final String ENDPOINT = "endpoint";
    // user > endpoint > status
    public static final String STATUS = "status";

    /**
     * status-type (String) :
     * "pending" : Endpoint is not yet in the session, but it is anticipated that he/she will
     *      join in the near future.
     * "dialing-out" : Focus has dialed out to connect the endpoint to the conference,
     *      but the endpoint is not yet in the roster (probably being authenticated).
     * "dialing-in" : Endpoint is dialing into the conference, not yet in the roster
     *      (probably being authenticated).
     * "alerting" : PSTN alerting or SIP 180 Ringing was returned for the outbound call;
     *      endpoint is being alerted.
     * "on-hold" : Active signaling dialog exists between an endpoint and a focus,
     *      but endpoint is "on-hold" for this conference, i.e., he/she is neither "hearing"
     *      the conference mix nor is his/her media being mixed in the conference.
     * "connected" : Endpoint is a participant in the conference. Depending on the media policies,
     *      he/she can send and receive media to and from other participants.
     * "disconnecting" : Focus is in the process of disconnecting the endpoint
     *      (e.g. in SIP a DISCONNECT or BYE was sent to the endpoint).
     * "disconnected" : Endpoint is not a participant in the conference, and no active dialog
     *      exists between the endpoint and the focus.
     * "muted-via-focus" : Active signaling dialog exists beween an endpoint and a focus and
     *      the endpoint can "listen" to the conference, but the endpoint's media is not being
     *      mixed into the conference.
     * "connect-fail" : Endpoint fails to join the conference by rejecting the conference call.
     */
    public static final String STATUS_PENDING = "pending";
    public static final String STATUS_DIALING_OUT = "dialing-out";
    public static final String STATUS_DIALING_IN = "dialing-in";
    public static final String STATUS_ALERTING = "alerting";
    public static final String STATUS_ON_HOLD = "on-hold";
    public static final String STATUS_CONNECTED = "connected";
    public static final String STATUS_DISCONNECTING = "disconnecting";
    public static final String STATUS_DISCONNECTED = "disconnected";
    public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
    public static final String STATUS_CONNECT_FAIL = "connect-fail";

    /**
     * conference-info : SIP status code (integer)
     */
    public static final String SIP_STATUS_CODE = "sipstatuscode";

    public HashMap<String, Bundle> mParticipants = new HashMap<String, Bundle>();

    public ImsConferenceState() {
    }

    public ImsConferenceState(Parcel in) {
        readFromParcel(in);
    }

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

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mParticipants.size());

        if (mParticipants.size() > 0) {
            Set<Entry<String, Bundle>> entries = mParticipants.entrySet();

            if (entries != null) {
                Iterator<Entry<String, Bundle>> iterator = entries.iterator();

                while (iterator.hasNext()) {
                    Entry<String, Bundle> entry = iterator.next();

                    out.writeString(entry.getKey());
                    out.writeParcelable(entry.getValue(), 0);
                }
            }
        }
    }

    private void readFromParcel(Parcel in) {
        int size = in.readInt();

        for (int i = 0; i < size; ++i) {
            String user = in.readString();
            Bundle state = in.readParcelable(null);
            mParticipants.put(user, state);
        }
    }

    public static final Creator<ImsConferenceState> CREATOR =
            new Creator<ImsConferenceState>() {
        @Override
        public ImsConferenceState createFromParcel(Parcel in) {
            return new ImsConferenceState(in);
        }

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

    /**
     * Translates an {@code ImsConferenceState} status type to a telecom connection state.
     *
     * @param status The status type.
     * @return The corresponding {@link android.telecom.Connection} state.
     */
    public static int getConnectionStateForStatus(String status) {
        if (status.equals(STATUS_PENDING)) {
            return Connection.STATE_INITIALIZING;
        } else if (status.equals(STATUS_DIALING_IN)) {
            return Connection.STATE_RINGING;
        } else if (status.equals(STATUS_ALERTING) ||
                status.equals(STATUS_DIALING_OUT)) {
            return Connection.STATE_DIALING;
        } else if (status.equals(STATUS_ON_HOLD)) {
            return Connection.STATE_HOLDING;
        } else if (status.equals(STATUS_CONNECTED) ||
                status.equals(STATUS_MUTED_VIA_FOCUS) ||
                status.equals(STATUS_DISCONNECTING)) {
            return Connection.STATE_ACTIVE;
        } else if (status.equals(STATUS_DISCONNECTED)) {
            return Connection.STATE_DISCONNECTED;
        }
        return Call.STATE_ACTIVE;
    }
}
