/*
 * 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.telephony.mbms;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.net.Uri;
import android.os.RemoteException;
import android.telephony.MbmsStreamingSession;
import android.telephony.mbms.vendor.IMbmsStreamingService;
import android.util.Log;

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

/**
 * Class used to represent a single MBMS stream. After a stream has been started with
 * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo,
 * StreamingServiceCallback, android.os.Handler)},
 * this class is used to hold information about the stream and control it.
 */
public class StreamingService {
    private static final String LOG_TAG = "MbmsStreamingService";

    /**
     * The state of a stream, reported via {@link StreamingServiceCallback#onStreamStateUpdated}
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({STATE_STOPPED, STATE_STARTED, STATE_STALLED})
    public @interface StreamingState {}
    public final static int STATE_STOPPED = 1;
    public final static int STATE_STARTED = 2;
    public final static int STATE_STALLED = 3;

    /**
     * The reason for a stream state change, reported via
     * {@link StreamingServiceCallback#onStreamStateUpdated}
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({REASON_BY_USER_REQUEST, REASON_END_OF_SESSION, REASON_FREQUENCY_CONFLICT,
            REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE,
            REASON_LEFT_MBMS_BROADCAST_AREA, REASON_NONE})
    public @interface StreamingStateChangeReason {}

    /**
     * Indicates that the middleware does not have a reason to provide for the state change.
     */
    public static final int REASON_NONE = 0;

    /**
     * State changed due to a call to {@link #stopStreaming()} or
     * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo,
     * StreamingServiceCallback, android.os.Handler)}
     */
    public static final int REASON_BY_USER_REQUEST = 1;

    /**
     * State changed due to the streaming session ending at the carrier.
     */
    public static final int REASON_END_OF_SESSION = 2;

    /**
     * State changed due to a frequency conflict with another requested stream.
     */
    public static final int REASON_FREQUENCY_CONFLICT = 3;

    /**
     * State changed due to the middleware running out of memory
     */
    public static final int REASON_OUT_OF_MEMORY = 4;

    /**
     * State changed due to the device leaving the home carrier's LTE network.
     */
    public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5;

    /**
     * State changed due to the device leaving the where this stream is being broadcast.
     */
    public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6;

    /**
     * The method of transmission currently used for a stream,
     * reported via {@link StreamingServiceCallback#onStreamMethodUpdated}
     */
    public final static int BROADCAST_METHOD = 1;
    public final static int UNICAST_METHOD   = 2;

    private final int mSubscriptionId;
    private final MbmsStreamingSession mParentSession;
    private final StreamingServiceInfo mServiceInfo;
    private final InternalStreamingServiceCallback mCallback;

    private IMbmsStreamingService mService;

    /**
     * @hide
     */
    public StreamingService(int subscriptionId,
            IMbmsStreamingService service,
            MbmsStreamingSession session,
            StreamingServiceInfo streamingServiceInfo,
            InternalStreamingServiceCallback callback) {
        mSubscriptionId = subscriptionId;
        mParentSession = session;
        mService = service;
        mServiceInfo = streamingServiceInfo;
        mCallback = callback;
    }

    /**
     * Retrieve the Uri used to play this stream.
     *
     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}.
     *
     * @return The {@link Uri} to pass to the streaming client, or {@code null} if an error
     *         occurred.
     */
    public @Nullable Uri getPlaybackUri() {
        if (mService == null) {
            throw new IllegalStateException("No streaming service attached");
        }

        try {
            return mService.getPlaybackUri(mSubscriptionId, mServiceInfo.getServiceId());
        } catch (RemoteException e) {
            Log.w(LOG_TAG, "Remote process died");
            mService = null;
            mParentSession.onStreamingServiceStopped(this);
            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
            return null;
        }
    }

    /**
     * Retrieve the {@link StreamingServiceInfo} corresponding to this stream.
     */
    public StreamingServiceInfo getInfo() {
        return mServiceInfo;
    }

    /**
     * Stop streaming this service. Further operations on this object will fail with an
     * {@link IllegalStateException}.
     *
     * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
     */
    public void stopStreaming() {
        if (mService == null) {
            throw new IllegalStateException("No streaming service attached");
        }

        try {
            mService.stopStreaming(mSubscriptionId, mServiceInfo.getServiceId());
        } catch (RemoteException e) {
            Log.w(LOG_TAG, "Remote process died");
            mService = null;
            sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
        } finally {
            mParentSession.onStreamingServiceStopped(this);
        }
    }

    /** @hide */
    public InternalStreamingServiceCallback getCallback() {
        return mCallback;
    }

    private void sendErrorToApp(int errorCode, String message) {
        try {
            mCallback.onError(errorCode, message);
        } catch (RemoteException e) {
            // Ignore, should not happen locally.
        }
    }
}

