/*
 * 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.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.MainThread;
import android.util.Log;

import com.android.tv.common.CommonConstants;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.actions.InputSetupActionUtils;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ChannelDataManager.Listener;
import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.data.epg.EpgInputWhiteList;
import com.android.tv.features.TvFeatures;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;

import com.google.android.tv.partner.support.EpgContract;

import dagger.android.AndroidInjection;
import dagger.android.ContributesAndroidInjector;

import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

/**
 * An activity to launch a TV input setup activity.
 *
 * <p>After setup activity is finished, all channels will be browsable.
 */
public class SetupPassthroughActivity extends Activity {
    private static final String TAG = "SetupPassthroughAct";
    private static final boolean DEBUG = false;

    private static final int REQUEST_START_SETUP_ACTIVITY = 200;

    private static ScanTimeoutMonitor sScanTimeoutMonitor;

    private TvInputInfo mTvInputInfo;
    private Intent mActivityAfterCompletion;
    private boolean mEpgFetcherDuringScan;
    @Inject EpgInputWhiteList mEpgInputWhiteList;
    @Inject TvInputManagerHelper mInputManager;
    @Inject SetupUtils mSetupUtils;
    @Inject ChannelDataManager mChannelDataManager;
    @Inject EpgFetcher mEpgFetcher;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        if (DEBUG) Log.d(TAG, "onCreate");
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        String inputId = intent.getStringExtra(InputSetupActionUtils.EXTRA_INPUT_ID);
        mTvInputInfo = mInputManager.getTvInputInfo(inputId);
        mActivityAfterCompletion = InputSetupActionUtils.getExtraActivityAfter(intent);
        boolean needToFetchEpg =
                mTvInputInfo != null && Utils.isInternalTvInput(this, mTvInputInfo.getId());
        if (needToFetchEpg) {
            // In case when the activity is restored, this flag should be restored as well.
            mEpgFetcherDuringScan = true;
        }
        if (savedInstanceState == null) {
            SoftPreconditions.checkArgument(
                    InputSetupActionUtils.hasInputSetupAction(intent),
                    TAG,
                    "Unsupported action %s",
                    intent.getAction());
            if (DEBUG) Log.d(TAG, "TvInputId " + inputId + " / TvInputInfo " + mTvInputInfo);
            if (mTvInputInfo == null) {
                Log.w(TAG, "There is no input with the ID " + inputId + ".");
                finish();
                return;
            }
            if (intent.getExtras() == null) {
                Log.w(TAG, "There is no extra info in the intent");
                finish();
                return;
            }
            Intent setupIntent = InputSetupActionUtils.getExtraSetupIntent(intent);
            if (DEBUG) Log.d(TAG, "Setup activity launch intent: " + setupIntent);
            if (setupIntent == null) {
                Log.w(TAG, "The input (" + mTvInputInfo.getId() + ") doesn't have setup.");
                finish();
                return;
            }
            SetupUtils.grantEpgPermission(this, mTvInputInfo.getServiceInfo().packageName);
            if (DEBUG) Log.d(TAG, "Activity after completion " + mActivityAfterCompletion);
            // If EXTRA_SETUP_INTENT is not removed, an infinite recursion happens during
            // setupIntent.putExtras(intent.getExtras()).
            Bundle extras = intent.getExtras();
            InputSetupActionUtils.removeSetupIntent(extras);
            setupIntent.putExtras(extras);
            try {
                ComponentName callingActivity = getCallingActivity();
                if (callingActivity == null
                        || !callingActivity.getPackageName().equals(CommonConstants.BASE_PACKAGE)) {
                   String name =
                        callingActivity == null ? "null" : callingActivity.getPackageName();
                    Log.w(TAG,
                            "Calling activity " + name + " is not trusted. Not forwarding intent.");
                    finish();
                    return;
                }
                startActivityForResult(setupIntent, REQUEST_START_SETUP_ACTIVITY);
            } catch (ActivityNotFoundException e) {
                Log.e(TAG, "Can't find activity: " + setupIntent.getComponent());
                finish();
                return;
            }
            if (needToFetchEpg) {
                if (sScanTimeoutMonitor == null) {
                    sScanTimeoutMonitor = new ScanTimeoutMonitor(mEpgFetcher, mChannelDataManager);
                }
                sScanTimeoutMonitor.startMonitoring();
                mEpgFetcher.onChannelScanStarted();
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, final int resultCode, final Intent data) {
        if (DEBUG)
            Log.d(TAG, "onActivityResult(" + requestCode + ",  " + resultCode + ",  " + data + ")");
        if (sScanTimeoutMonitor != null) {
            sScanTimeoutMonitor.stopMonitoring();
        }
        // Note: It's not guaranteed that this method is always called after scanning.
        boolean setupComplete =
                requestCode == REQUEST_START_SETUP_ACTIVITY && resultCode == Activity.RESULT_OK;
        // Tells EpgFetcher that channel source setup is finished.

        if (mEpgFetcherDuringScan) {
            mEpgFetcher.onChannelScanFinished();
        }
        if (!setupComplete) {
            setResult(resultCode, data);
            finish();
            return;
        }
        if (TvFeatures.CLOUD_EPG_FOR_3RD_PARTY.isEnabled(this)
                && data != null
                && data.getBooleanExtra(EpgContract.EXTRA_USE_CLOUD_EPG, false)) {
            if (DEBUG) Log.d(TAG, "extra " + data.getExtras());
            String inputId = data.getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
            if (mEpgInputWhiteList.isInputWhiteListed(inputId)) {
                mEpgFetcher.fetchImmediately();
            }
        }

        if (mTvInputInfo == null) {
            Log.w(
                    TAG,
                    "There is no input with ID "
                            + getIntent().getStringExtra(InputSetupActionUtils.EXTRA_INPUT_ID)
                            + ".");
            setResult(resultCode, data);
            finish();
            return;
        }
        mSetupUtils.onTvInputSetupFinished(
                mTvInputInfo.getId(),
                () -> {
                    if (mActivityAfterCompletion != null) {
                        try {
                            startActivity(mActivityAfterCompletion);
                        } catch (ActivityNotFoundException e) {
                            Log.w(TAG, "Activity launch failed", e);
                        }
                    }
                    setResult(resultCode, data);
                    finish();
                });
    }

    /**
     * Monitors the scan progress and notifies the timeout of the scanning. The purpose of this
     * monitor is to call EpgFetcher.onChannelScanFinished() in case when
     * SetupPassthroughActivity.onActivityResult() is not called properly. b/36008534
     */
    @MainThread
    private static class ScanTimeoutMonitor {
        // Set timeout long enough. The message in Sony TV says the scanning takes about 30 minutes.
        private static final long SCAN_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(30);

        private final EpgFetcher mEpgFetcher;
        private final ChannelDataManager mChannelDataManager;
        private final Handler mHandler = new Handler(Looper.getMainLooper());
        private final Runnable mScanTimeoutRunnable =
                () -> {
                    Log.w(
                            TAG,
                            "No channels has been added for a while."
                                    + " The scan might have finished unexpectedly.");
                    onScanTimedOut();
                };
        private final Listener mChannelDataManagerListener =
                new Listener() {
                    @Override
                    public void onLoadFinished() {
                        setupTimer();
                    }

                    @Override
                    public void onChannelListUpdated() {
                        setupTimer();
                    }

                    @Override
                    public void onChannelBrowsableChanged() {}
                };
        private boolean mStarted;

        private ScanTimeoutMonitor(EpgFetcher epgFetcher, ChannelDataManager mChannelDataManager) {
            mEpgFetcher = epgFetcher;
            this.mChannelDataManager = mChannelDataManager;
        }

        private void startMonitoring() {
            if (!mStarted) {
                mStarted = true;
                mChannelDataManager.addListener(mChannelDataManagerListener);
            }
            if (mChannelDataManager.isDbLoadFinished()) {
                setupTimer();
            }
        }

        private void stopMonitoring() {
            if (mStarted) {
                mStarted = false;
                mHandler.removeCallbacks(mScanTimeoutRunnable);
                mChannelDataManager.removeListener(mChannelDataManagerListener);
            }
        }

        private void setupTimer() {
            mHandler.removeCallbacks(mScanTimeoutRunnable);
            mHandler.postDelayed(mScanTimeoutRunnable, SCAN_TIMEOUT_MS);
        }

        private void onScanTimedOut() {
            stopMonitoring();
            mEpgFetcher.onChannelScanFinished();
        }
    }

    /** Exports {@link MainActivity} for Dagger codegen to create the appropriate injector. */
    @dagger.Module
    public abstract static class Module {
        @ContributesAndroidInjector
        abstract SetupPassthroughActivity contributesSetupPassthroughActivity();
    }
}
