/*
 * 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.tuner.tvinput;

import android.annotation.TargetApi;
import android.content.Context;
import android.media.PlaybackParams;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputService;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.exoplayer.audio.AudioCapabilities;
import com.android.tv.tuner.R;
import com.android.tv.tuner.cc.CaptionLayout;
import com.android.tv.tuner.cc.CaptionTrackRenderer;
import com.android.tv.tuner.data.Cea708Data.CaptionEvent;
import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.util.GlobalSettingsUtils;
import com.android.tv.tuner.util.StatusTextUtils;
import com.android.tv.tuner.util.SystemPropertiesProxy;

/**
 * Provides a tuner TV input session. It handles Overlay UI works. Main tuner input functions
 * are implemented in {@link TunerSessionWorker}.
 */
public class TunerSession extends TvInputService.Session implements Handler.Callback {
    private static final String TAG = "TunerSession";
    private static final boolean DEBUG = false;
    private static final String USBTUNER_SHOW_DEBUG = "persist.tv.tuner.show_debug";

    public static final int MSG_UI_SHOW_MESSAGE = 1;
    public static final int MSG_UI_HIDE_MESSAGE = 2;
    public static final int MSG_UI_SHOW_AUDIO_UNPLAYABLE = 3;
    public static final int MSG_UI_HIDE_AUDIO_UNPLAYABLE = 4;
    public static final int MSG_UI_PROCESS_CAPTION_TRACK = 5;
    public static final int MSG_UI_START_CAPTION_TRACK = 6;
    public static final int MSG_UI_STOP_CAPTION_TRACK = 7;
    public static final int MSG_UI_RESET_CAPTION_TRACK = 8;
    public static final int MSG_UI_SET_STATUS_TEXT = 9;
    public static final int MSG_UI_TOAST_RESCAN_NEEDED = 10;

    private final Context mContext;
    private final Handler mUiHandler;
    private final View mOverlayView;
    private final TextView mMessageView;
    private final TextView mStatusView;
    private final TextView mAudioStatusView;
    private final ViewGroup mMessageLayout;
    private final CaptionTrackRenderer mCaptionTrackRenderer;
    private final TunerSessionWorker mSessionWorker;
    private boolean mReleased = false;
    private boolean mPlayPaused;
    private long mTuneStartTimestamp;

    public TunerSession(Context context, ChannelDataManager channelDataManager,
            BufferManager bufferManager) {
        super(context);
        mContext = context;
        mUiHandler = new Handler(this);
        LayoutInflater inflater = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mOverlayView = inflater.inflate(R.layout.ut_overlay_view, null);
        mMessageLayout = (ViewGroup) mOverlayView.findViewById(R.id.message_layout);
        mMessageLayout.setVisibility(View.INVISIBLE);
        mMessageView = (TextView) mOverlayView.findViewById(R.id.message);
        mStatusView = (TextView) mOverlayView.findViewById(R.id.tuner_status);
        boolean showDebug = SystemPropertiesProxy.getBoolean(USBTUNER_SHOW_DEBUG, false);
        mStatusView.setVisibility(showDebug ? View.VISIBLE : View.INVISIBLE);
        mAudioStatusView = (TextView) mOverlayView.findViewById(R.id.audio_status);
        mAudioStatusView.setVisibility(View.INVISIBLE);
        mAudioStatusView.setText(Html.fromHtml(StatusTextUtils.getAudioWarningInHTML(
                context.getString(R.string.ut_surround_sound_disabled))));
        CaptionLayout captionLayout = (CaptionLayout) mOverlayView.findViewById(R.id.caption);
        mCaptionTrackRenderer = new CaptionTrackRenderer(captionLayout);
        mSessionWorker = new TunerSessionWorker(context, channelDataManager,
                bufferManager, this);
    }

    public boolean isReleased() {
        return mReleased;
    }

    @Override
    public View onCreateOverlayView() {
        return mOverlayView;
    }

    @Override
    public boolean onSelectTrack(int type, String trackId) {
        mSessionWorker.sendMessage(TunerSessionWorker.MSG_SELECT_TRACK, type, 0, trackId);
        return false;
    }

    @Override
    public void onSetCaptionEnabled(boolean enabled) {
        mSessionWorker.setCaptionEnabled(enabled);
    }

    @Override
    public void onSetStreamVolume(float volume) {
        mSessionWorker.setStreamVolume(volume);
    }

    @Override
    public boolean onSetSurface(Surface surface) {
        mSessionWorker.setSurface(surface);
        return true;
    }

    @Override
    public void onTimeShiftPause() {
        mSessionWorker.sendMessage(TunerSessionWorker.MSG_TIMESHIFT_PAUSE);
        mPlayPaused = true;
    }

    @Override
    public void onTimeShiftResume() {
        mSessionWorker.sendMessage(TunerSessionWorker.MSG_TIMESHIFT_RESUME);
        mPlayPaused = false;
    }

    @Override
    public void onTimeShiftSeekTo(long timeMs) {
        if (DEBUG) Log.d(TAG, "Timeshift seekTo requested position: " + timeMs / 1000);
        mSessionWorker.sendMessage(TunerSessionWorker.MSG_TIMESHIFT_SEEK_TO,
                mPlayPaused ? 1 : 0, 0, timeMs);
    }

    @Override
    public void onTimeShiftSetPlaybackParams(PlaybackParams params) {
        mSessionWorker.sendMessage(
                TunerSessionWorker.MSG_TIMESHIFT_SET_PLAYBACKPARAMS, params);
    }

    @Override
    public long onTimeShiftGetStartPosition() {
        return mSessionWorker.getStartPosition();
    }

    @Override
    public long onTimeShiftGetCurrentPosition() {
        return mSessionWorker.getCurrentPosition();
    }

    @Override
    public boolean onTune(Uri channelUri) {
        if (DEBUG) {
            Log.d(TAG, "onTune to " + channelUri != null ? channelUri.toString() : "");
        }
        if (channelUri == null) {
            Log.w(TAG, "onTune() is failed due to null channelUri.");
            mSessionWorker.stopTune();
            return false;
        }
        mTuneStartTimestamp = SystemClock.elapsedRealtime();
        mSessionWorker.tune(channelUri);
        mPlayPaused = false;
        return true;
    }

    @TargetApi(Build.VERSION_CODES.N)
    @Override
    public void onTimeShiftPlay(Uri recordUri) {
        if (recordUri == null) {
            Log.w(TAG, "onTimeShiftPlay() is failed due to null channelUri.");
            mSessionWorker.stopTune();
            return;
        }
        mTuneStartTimestamp = SystemClock.elapsedRealtime();
        mSessionWorker.tune(recordUri);
        mPlayPaused = false;
    }

    @Override
    public void onUnblockContent(TvContentRating unblockedRating) {
        mSessionWorker.sendMessage(TunerSessionWorker.MSG_UNBLOCKED_RATING,
                unblockedRating);
    }

    @Override
    public void onRelease() {
        if (DEBUG) {
            Log.d(TAG, "onRelease");
        }
        mReleased = true;
        mSessionWorker.release();
        mUiHandler.removeCallbacksAndMessages(null);
    }

    /**
     * Sets {@link AudioCapabilities}.
     */
    public void setAudioCapabilities(AudioCapabilities audioCapabilities) {
        mSessionWorker.sendMessage(TunerSessionWorker.MSG_AUDIO_CAPABILITIES_CHANGED,
                audioCapabilities);
    }

    @Override
    public void notifyVideoAvailable() {
        super.notifyVideoAvailable();
        if (mTuneStartTimestamp != 0) {
            Log.i(TAG, "[Profiler] Video available in "
                    + (SystemClock.elapsedRealtime() - mTuneStartTimestamp) + " ms");
            mTuneStartTimestamp = 0;
        }
    }

    @Override
    public void notifyVideoUnavailable(int reason) {
        super.notifyVideoUnavailable(reason);
        if (reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING
                && reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL) {
            notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE);
        }
    }

    public void sendUiMessage(int message) {
        mUiHandler.sendEmptyMessage(message);
    }

    public void sendUiMessage(int message, Object object) {
        mUiHandler.obtainMessage(message, object).sendToTarget();
    }

    public void sendUiMessage(int message, int arg1, int arg2, Object object) {
        mUiHandler.obtainMessage(message, arg1, arg2, object).sendToTarget();
    }

    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_UI_SHOW_MESSAGE: {
                mMessageView.setText((String) msg.obj);
                mMessageLayout.setVisibility(View.VISIBLE);
                return true;
            }
            case MSG_UI_HIDE_MESSAGE: {
                mMessageLayout.setVisibility(View.INVISIBLE);
                return true;
            }
            case MSG_UI_SHOW_AUDIO_UNPLAYABLE: {
                // Showing message of enabling surround sound only when global surround sound
                // setting is "never".
                final int value = GlobalSettingsUtils.getEncodedSurroundOutputSettings(mContext);
                if (value == GlobalSettingsUtils.ENCODED_SURROUND_OUTPUT_NEVER) {
                    mAudioStatusView.setVisibility(View.VISIBLE);
                } else {
                    Log.e(TAG, "Audio is unavailable, surround sound setting is " + value);
                }
                return true;
            }
            case MSG_UI_HIDE_AUDIO_UNPLAYABLE: {
                mAudioStatusView.setVisibility(View.INVISIBLE);
                return true;
            }
            case MSG_UI_PROCESS_CAPTION_TRACK: {
                mCaptionTrackRenderer.processCaptionEvent((CaptionEvent) msg.obj);
                return true;
            }
            case MSG_UI_START_CAPTION_TRACK: {
                mCaptionTrackRenderer.start((AtscCaptionTrack) msg.obj);
                return true;
            }
            case MSG_UI_STOP_CAPTION_TRACK: {
                mCaptionTrackRenderer.stop();
                return true;
            }
            case MSG_UI_RESET_CAPTION_TRACK: {
                mCaptionTrackRenderer.reset();
                return true;
            }
            case MSG_UI_SET_STATUS_TEXT: {
                mStatusView.setText((CharSequence) msg.obj);
                return true;
            }
            case MSG_UI_TOAST_RESCAN_NEEDED: {
                Toast.makeText(mContext, R.string.ut_rescan_needed, Toast.LENGTH_LONG).show();
                return true;
            }
        }
        return false;
    }
}
