/*
 * Copyright (C) 2015 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.tv;

import android.annotation.TargetApi;
import android.content.Context;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputInfo;
import android.media.tv.TvRecordingClient;
import android.media.tv.TvRecordingClient.RecordingCallback;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView;
import android.media.tv.TvView.TvInputCallback;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;

import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.TunableTvView.OnTuneListener;
import com.android.tv.util.TvInputManagerHelper;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Manages input sessions.
 * Responsible for:
 * <ul>
 *     <li>Manage {@link TvView} sessions and recording sessions</li>
 *     <li>Manage capabilities (conflict)</li>
 * </ul>
 * <p>
 * As TvView's methods should be called on the main thread and the {@link RecordingSession} should
 * look at the state of the {@link TvViewSession} when it calls the framework methods, the framework
 * calls in RecordingSession are made on the main thread not to introduce the multi-thread problems.
 */
@TargetApi(Build.VERSION_CODES.N)
public class InputSessionManager {
    private static final String TAG = "InputSessionManager";
    private static final boolean DEBUG = false;

    private final Context mContext;
    private final TvInputManagerHelper mInputManager;
    private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
    private final Set<TvViewSession> mTvViewSessions = new ArraySet<>();
    private final Set<RecordingSession> mRecordingSessions =
            Collections.synchronizedSet(new ArraySet<>());
    private final Set<OnTvViewChannelChangeListener> mOnTvViewChannelChangeListeners =
            new ArraySet<>();

    public InputSessionManager(Context context) {
        mContext = context.getApplicationContext();
        mInputManager = TvApplication.getSingletons(context).getTvInputManagerHelper();
    }

    /**
     * Creates the session for {@link TvView}.
     * <p>
     * Do not call {@link TvView#setCallback} after the session is created.
     */
    @MainThread
    @NonNull
    public TvViewSession createTvViewSession(TvView tvView, TunableTvView tunableTvView,
            TvInputCallback callback) {
        TvViewSession session = new TvViewSession(tvView, tunableTvView, callback);
        mTvViewSessions.add(session);
        if (DEBUG) Log.d(TAG, "TvView session created: " + session);
        return session;
    }

    /**
     * Releases the {@link TvView} session.
     */
    @MainThread
    public void releaseTvViewSession(TvViewSession session) {
        mTvViewSessions.remove(session);
        session.reset();
        if (DEBUG) Log.d(TAG, "TvView session released: " + session);
    }

    /**
     * Creates the session for recording.
     */
    @NonNull
    public RecordingSession createRecordingSession(String inputId, String tag,
            RecordingCallback callback, Handler handler, long endTimeMs) {
        RecordingSession session = new RecordingSession(inputId, tag, callback, handler, endTimeMs);
        mRecordingSessions.add(session);
        if (DEBUG) Log.d(TAG, "Recording session created: " + session);
        return session;
    }

    /**
     * Releases the recording session.
     */
    public void releaseRecordingSession(RecordingSession session) {
        mRecordingSessions.remove(session);
        session.release();
        if (DEBUG) Log.d(TAG, "Recording session released: " + session);
    }

    /**
     * Adds the {@link OnTvViewChannelChangeListener}.
     */
    @MainThread
    public void addOnTvViewChannelChangeListener(OnTvViewChannelChangeListener listener) {
        mOnTvViewChannelChangeListeners.add(listener);
    }

    /**
     * Removes the {@link OnTvViewChannelChangeListener}.
     */
    @MainThread
    public void removeOnTvViewChannelChangeListener(OnTvViewChannelChangeListener listener) {
        mOnTvViewChannelChangeListeners.remove(listener);
    }

    @MainThread
    void notifyTvViewChannelChange(Uri channelUri) {
        for (OnTvViewChannelChangeListener l : mOnTvViewChannelChangeListeners) {
            l.onTvViewChannelChange(channelUri);
        }
    }

    /**
     * Returns the current {@link TvView} channel.
     */
    @MainThread
    public Uri getCurrentTvViewChannelUri() {
        for (TvViewSession session : mTvViewSessions) {
            if (session.mTuned) {
                return session.mChannelUri;
            }
        }
        return null;
    }

    /**
     * Retruns the earliest end time of recording sessions in progress of the certain TV input.
     */
    @MainThread
    public Long getEarliestRecordingSessionEndTimeMs(String inputId) {
        long timeMs = Long.MAX_VALUE;
        synchronized (mRecordingSessions) {
            for (RecordingSession session : mRecordingSessions) {
                if (session.mTuned && TextUtils.equals(inputId, session.mInputId)) {
                    if (session.mEndTimeMs < timeMs) {
                        timeMs = session.mEndTimeMs;
                    }
                }
            }
        }
        return timeMs == Long.MAX_VALUE ? null : timeMs;
    }

    @MainThread
    int getTunedTvViewSessionCount(String inputId) {
        int tunedCount = 0;
        for (TvViewSession session : mTvViewSessions) {
            if (session.mTuned && Objects.equals(inputId, session.mInputId)) {
                ++tunedCount;
            }
        }
        return tunedCount;
    }

    @MainThread
    boolean isTunedForTvView(Uri channelUri) {
        for (TvViewSession session : mTvViewSessions) {
            if (session.mTuned && Objects.equals(channelUri, session.mChannelUri)) {
                return true;
            }
        }
        return false;
    }

    int getTunedRecordingSessionCount(String inputId) {
        synchronized (mRecordingSessions) {
            int tunedCount = 0;
            for (RecordingSession session : mRecordingSessions) {
                if (session.mTuned && Objects.equals(inputId, session.mInputId)) {
                    ++tunedCount;
                }
            }
            return tunedCount;
        }
    }

    boolean isTunedForRecording(Uri channelUri) {
        synchronized (mRecordingSessions) {
            for (RecordingSession session : mRecordingSessions) {
                if (session.mTuned && Objects.equals(channelUri, session.mChannelUri)) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * The session for {@link TvView}.
     * <p>
     * The methods which create or release session for the TV input should be called through this
     * session.
     */
    @MainThread
    public class TvViewSession {
        private final TvView mTvView;
        private final TunableTvView mTunableTvView;
        private final TvInputCallback mCallback;
        private Channel mChannel;
        private String mInputId;
        private Uri mChannelUri;
        private Bundle mParams;
        private OnTuneListener mOnTuneListener;
        private boolean mTuned;
        private boolean mNeedToBeRetuned;

        TvViewSession(TvView tvView, TunableTvView tunableTvView, TvInputCallback callback) {
            mTvView = tvView;
            mTunableTvView = tunableTvView;
            mCallback = callback;
            mTvView.setCallback(new DelegateTvInputCallback(mCallback) {
                @Override
                public void onConnectionFailed(String inputId) {
                    if (DEBUG) Log.d(TAG, "TvViewSession: commection failed");
                    mTuned = false;
                    mNeedToBeRetuned = false;
                    super.onConnectionFailed(inputId);
                    notifyTvViewChannelChange(null);
                }

                @Override
                public void onDisconnected(String inputId) {
                    if (DEBUG) Log.d(TAG, "TvViewSession: disconnected");
                    mTuned = false;
                    mNeedToBeRetuned = false;
                    super.onDisconnected(inputId);
                    notifyTvViewChannelChange(null);
                }
            });
        }

        /**
         * Tunes to the channel.
         * <p>
         * As this is called only for the warming up, there's no need to be retuned.
         */
        public void tune(String inputId, Uri channelUri) {
            if (DEBUG) {
                Log.d(TAG, "warm-up tune: {input=" + inputId + ", channelUri=" + channelUri + "}");
            }
            mInputId = inputId;
            mChannelUri = channelUri;
            mTuned = true;
            mNeedToBeRetuned = false;
            mTvView.tune(inputId, channelUri);
            notifyTvViewChannelChange(channelUri);
        }

        /**
         * Tunes to the channel.
         */
        public void tune(Channel channel, Bundle params, OnTuneListener listener) {
            if (DEBUG) {
                Log.d(TAG, "tune: {session=" + this + ", channel=" + channel + ", params=" + params
                        + ", listener=" + listener + ", mTuned=" + mTuned + "}");
            }
            mChannel = channel;
            mInputId = channel.getInputId();
            mChannelUri = channel.getUri();
            mParams = params;
            mOnTuneListener = listener;
            TvInputInfo input = mInputManager.getTvInputInfo(mInputId);
            if (input == null || (input.canRecord() && !isTunedForRecording(mChannelUri)
                    && getTunedRecordingSessionCount(mInputId) >= input.getTunerCount())) {
                if (DEBUG) {
                    if (input == null) {
                        Log.d(TAG, "Can't find input for input ID: " + mInputId);
                    } else {
                        Log.d(TAG, "No more tuners to tune for input: " + input);
                    }
                }
                mCallback.onConnectionFailed(mInputId);
                // Release the previous session to not to hold the unnecessary session.
                resetByRecording();
                return;
            }
            mTuned = true;
            mNeedToBeRetuned = false;
            mTvView.tune(mInputId, mChannelUri, params);
            notifyTvViewChannelChange(mChannelUri);
        }

        void retune() {
            if (DEBUG) Log.d(TAG, "Retune requested.");
            if (mNeedToBeRetuned) {
                if (DEBUG) Log.d(TAG, "Retuning: {channel=" + mChannel + "}");
                mTunableTvView.tuneTo(mChannel, mParams, mOnTuneListener);
                mNeedToBeRetuned = false;
            }
        }

        /**
         * Plays a given recorded TV program.
         *
         * @see TvView#timeShiftPlay
         */
        public void timeShiftPlay(String inputId, Uri recordedProgramUri) {
            mTuned = false;
            mNeedToBeRetuned = false;
            mTvView.timeShiftPlay(inputId, recordedProgramUri);
            notifyTvViewChannelChange(null);
        }

        /**
         * Resets this TvView.
         */
        public void reset() {
            if (DEBUG) Log.d(TAG, "Reset TvView session");
            mTuned = false;
            mTvView.reset();
            mNeedToBeRetuned = false;
            notifyTvViewChannelChange(null);
        }

        void resetByRecording() {
            mCallback.onVideoUnavailable(mInputId,
                    TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE);
            if (mTuned) {
                if (DEBUG) Log.d(TAG, "Reset TvView session by recording");
                mTunableTvView.resetByRecording();
                reset();
            }
            mNeedToBeRetuned = true;
        }
    }

    /**
     * The session for recording.
     * <p>
     * The caller is responsible for releasing the session when the error occurs.
     */
    public class RecordingSession {
        private final String mInputId;
        private Uri mChannelUri;
        private final RecordingCallback mCallback;
        private final Handler mHandler;
        private volatile long mEndTimeMs;
        private TvRecordingClient mClient;
        private boolean mTuned;

        RecordingSession(String inputId, String tag, RecordingCallback callback,
                Handler handler, long endTimeMs) {
            mInputId = inputId;
            mCallback = callback;
            mHandler = handler;
            mClient = new TvRecordingClient(mContext, tag, callback, handler);
            mEndTimeMs = endTimeMs;
        }

        void release() {
            if (DEBUG) Log.d(TAG, "Release of recording session requested.");
            runOnHandler(mMainThreadHandler, new Runnable() {
                @Override
                public void run() {
                    if (DEBUG) Log.d(TAG, "Releasing of recording session.");
                    mTuned = false;
                    mClient.release();
                    mClient = null;
                    for (TvViewSession session : mTvViewSessions) {
                        if (DEBUG) {
                            Log.d(TAG, "Finding TvView sessions for retune: {tuned="
                                    + session.mTuned + ", inputId=" + session.mInputId
                                    + ", session=" + session + "}");
                        }
                        if (!session.mTuned && Objects.equals(session.mInputId, mInputId)) {
                            session.retune();
                            break;
                        }
                    }
                }
            });
        }

        /**
         * Tunes to the channel for recording.
         */
        public void tune(String inputId, Uri channelUri) {
            runOnHandler(mMainThreadHandler, new Runnable() {
                @Override
                public void run() {
                    int tunedRecordingSessionCount = getTunedRecordingSessionCount(inputId);
                    TvInputInfo input = mInputManager.getTvInputInfo(inputId);
                    if (input == null || !input.canRecord()
                            || input.getTunerCount() <= tunedRecordingSessionCount) {
                        runOnHandler(mHandler, new Runnable() {
                            @Override
                            public void run() {
                                mCallback.onConnectionFailed(inputId);
                            }
                        });
                        return;
                    }
                    mTuned = true;
                    int tunedTuneSessionCount = getTunedTvViewSessionCount(inputId);
                    if (!isTunedForTvView(channelUri) && tunedTuneSessionCount > 0
                            && tunedRecordingSessionCount + tunedTuneSessionCount
                                    >= input.getTunerCount()) {
                        for (TvViewSession session : mTvViewSessions) {
                            if (session.mTuned && Objects.equals(session.mInputId, inputId)
                                    && !isTunedForRecording(session.mChannelUri)) {
                                session.resetByRecording();
                                break;
                            }
                        }
                    }
                    mChannelUri = channelUri;
                    mClient.tune(inputId, channelUri);
                }
            });
        }

        /**
         * Starts recording.
         */
        public void startRecording(Uri programHintUri) {
            mClient.startRecording(programHintUri);
        }

        /**
         * Stops recording.
         */
        public void stopRecording() {
            mClient.stopRecording();
        }

        /**
         * Sets recording session's ending time.
         */
        public void setEndTimeMs(long endTimeMs) {
            mEndTimeMs = endTimeMs;
        }

        private void runOnHandler(Handler handler, Runnable runnable) {
            if (Looper.myLooper() == handler.getLooper()) {
                runnable.run();
            } else {
                handler.post(runnable);
            }
        }
    }

    private static class DelegateTvInputCallback extends TvInputCallback {
        private final TvInputCallback mDelegate;

        DelegateTvInputCallback(TvInputCallback delegate) {
            mDelegate = delegate;
        }

        @Override
        public void onConnectionFailed(String inputId) {
            mDelegate.onConnectionFailed(inputId);
        }

        @Override
        public void onDisconnected(String inputId) {
            mDelegate.onDisconnected(inputId);
        }

        @Override
        public void onChannelRetuned(String inputId, Uri channelUri) {
            mDelegate.onChannelRetuned(inputId, channelUri);
        }

        @Override
        public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
            mDelegate.onTracksChanged(inputId, tracks);
        }

        @Override
        public void onTrackSelected(String inputId, int type, String trackId) {
            mDelegate.onTrackSelected(inputId, type, trackId);
        }

        @Override
        public void onVideoSizeChanged(String inputId, int width, int height) {
            mDelegate.onVideoSizeChanged(inputId, width, height);
        }

        @Override
        public void onVideoAvailable(String inputId) {
            mDelegate.onVideoAvailable(inputId);
        }

        @Override
        public void onVideoUnavailable(String inputId, int reason) {
            mDelegate.onVideoUnavailable(inputId, reason);
        }

        @Override
        public void onContentAllowed(String inputId) {
            mDelegate.onContentAllowed(inputId);
        }

        @Override
        public void onContentBlocked(String inputId, TvContentRating rating) {
            mDelegate.onContentBlocked(inputId, rating);
        }

        @Override
        public void onTimeShiftStatusChanged(String inputId, int status) {
            mDelegate.onTimeShiftStatusChanged(inputId, status);
        }
    }

    /**
     * Called when the {@link TvView} channel is changed.
     */
    public interface OnTvViewChannelChangeListener {
        void onTvViewChannelChange(@Nullable Uri channelUri);
    }
}
