/*
 * 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.TvTrackInfo;
import android.media.tv.TvView;
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.compat.TvRecordingClientCompat;
import com.android.tv.common.compat.TvRecordingClientCompat.RecordingCallbackCompat;
import com.android.tv.common.compat.TvViewCompat;
import com.android.tv.common.compat.TvViewCompat.TvInputCallbackCompat;
import com.android.tv.data.api.Channel;
import com.android.tv.dvr.DvrTvView;
import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.TunableTvView.OnTuneListener;
import com.android.tv.ui.api.TunableTvViewPlayingApi;
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>Manage capabilities (conflict)
 * </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<>();
    private final Set<OnRecordingSessionChangeListener> mOnRecordingSessionChangeListeners =
            new ArraySet<>();

    public InputSessionManager(Context context) {
        mContext = context.getApplicationContext();
        mInputManager = TvSingletons.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(
            TvViewCompat tvView,
            TunableTvViewPlayingApi tunableTvView,
            TvInputCallbackCompat 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,
            RecordingCallbackCompat 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);
        for (OnRecordingSessionChangeListener listener : mOnRecordingSessionChangeListeners) {
            listener.onRecordingSessionChange(true, mRecordingSessions.size());
        }
        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);
        for (OnRecordingSessionChangeListener listener : mOnRecordingSessionChangeListeners) {
            listener.onRecordingSessionChange(false, mRecordingSessions.size());
        }
    }

    /** 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);
        }
    }

    /** Adds the {@link OnRecordingSessionChangeListener}. */
    public void addOnRecordingSessionChangeListener(OnRecordingSessionChangeListener listener) {
        mOnRecordingSessionChangeListeners.add(listener);
    }

    /** Removes the {@link OnRecordingSessionChangeListener}. */
    public void removeRecordingSessionChangeListener(OnRecordingSessionChangeListener listener) {
        mOnRecordingSessionChangeListeners.remove(listener);
    }

    /** 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 TvViewCompat mTvView;
        private final TunableTvViewPlayingApi mTunableTvView;
        private final TvInputCallbackCompat mCallback;
        private final boolean mIsDvrSession;
        private Channel mChannel;
        private String mInputId;
        private Uri mChannelUri;
        private Bundle mParams;
        private OnTuneListener mOnTuneListener;
        private boolean mTuned;
        private boolean mNeedToBeRetuned;

        TvViewSession(
                TvViewCompat tvView,
                TunableTvViewPlayingApi tunableTvView,
                TvInputCallbackCompat callback) {
            mTvView = tvView;
            mTunableTvView = tunableTvView;
            mCallback = callback;
            mIsDvrSession = tunableTvView instanceof DvrTvView;
            mTvView.setCallback(
                    new DelegateTvInputCallback(mCallback) {
                        @Override
                        public void onConnectionFailed(String inputId) {
                            if (DEBUG) Log.d(TAG, "TvViewSession: connection 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 (mIsDvrSession) {
                Log.w(TAG, "DVR session should not call retune()!");
                return;
            }
            if (mNeedToBeRetuned) {
                if (DEBUG) Log.d(TAG, "Retuning: {channel=" + mChannel + "}");
                ((TunableTvView) 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 (mIsDvrSession) {
                Log.w(TAG, "DVR session should not call resetByRecording()!");
                return;
            }
            if (mTuned) {
                if (DEBUG) Log.d(TAG, "Reset TvView session by recording");
                ((TunableTvView) 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 RecordingCallbackCompat mCallback;
        private final Handler mHandler;
        private volatile long mEndTimeMs;
        private TvRecordingClientCompat mClient;
        private boolean mTuned;

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

        void release() {
            if (DEBUG) Log.d(TAG, "Release of recording session requested.");
            runOnHandler(
                    mMainThreadHandler,
                    () -> {
                        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,
                    () -> {
                        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 TvInputCallbackCompat {
        private final TvInputCallbackCompat mDelegate;

        DelegateTvInputCallback(TvInputCallbackCompat 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);
        }

        @Override
        public void onSignalStrength(String inputId, int value) {
            mDelegate.onSignalStrength(inputId, value);
        }
    }

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

    /** Called when recording session is created or destroyed. */
    public interface OnRecordingSessionChangeListener {
        void onRecordingSessionChange(boolean create, int count);
    }
}
