/*
 * 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 com.android.retaildemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.VideoView;

import java.io.File;

/**
 * This is the activity for playing the retail demo video. This will also try to keep
 * the screen on.
 *
 * This will check for the demo video in {@link Environment#getDataPreloadsDemoDirectory()} or
 * {@link Context#getObbDir()}. If the demo video is not present, it will run a task to download it
 * from the specified url.
 */
public class DemoPlayer extends Activity implements DownloadVideoTask.ResultListener {

    private static final String TAG = "DemoPlayer";
    private static final boolean DEBUG = false;

    /**
     * We save the real elapsed time to serve as an indication for downloading the demo video
     * for the next device boot. The device could boot fast at times and could result in
     * skipping the download during the next boot sessions. To be safe from cases like this, we
     * add this offset to the real elapsed time.
     */
    private static final long REAL_ELAPSED_TIME_OFFSET_MS = 60 * 1000; // 1 min

    /**
     * Maximum amount of time to wait for demo user to set up.
     * After it the user can tap the screen to exit
     */
    private static final long READY_TO_TAP_MAX_DELAY_MS = 60 * 1000; // 1 min

    private PowerManager mPowerManager;

    private VideoView mVideoView;
    private String mDownloadPath;
    private boolean mUsingDownloadedVideo;
    private Handler mHandler;
    private boolean mReadyToTap;
    private SettingsObserver mSettingsObserver;
    private File mPreloadedVideoFile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Keep screen on
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        setContentView(R.layout.retail_video);

        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mHandler = new Handler();
        final String preloadedFileName = getString(R.string.retail_demo_video_file_name);
        mPreloadedVideoFile = new File(Environment.getDataPreloadsDemoDirectory(),
                preloadedFileName);
        mDownloadPath = getObbDir().getPath() + File.separator + preloadedFileName;
        mVideoView = (VideoView) findViewById(R.id.video_content);

        // Start playing the video when it is ready
        mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                mediaPlayer.setLooping(true);
                mVideoView.start();
            }
        });

        mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                if (mUsingDownloadedVideo && mPreloadedVideoFile.exists()) {
                    if (DEBUG) Log.d(TAG, "Error using the downloaded video, "
                            + "falling back to the preloaded video at " + mPreloadedVideoFile);
                    mUsingDownloadedVideo = false;
                    setVideoPath(mPreloadedVideoFile.getPath());
                    // And delete the downloaded video so that we don't try to use it
                    // again next time.
                    new File(mDownloadPath).delete();
                } else {
                    displayFallbackView();
                }
                return true;
            }
        });

        mReadyToTap = isUserSetupComplete();
        if (!mReadyToTap) {
            // Wait for setup to finish
            mSettingsObserver = new SettingsObserver();
            mSettingsObserver.register();
            // Allow user to exit the demo player if setup takes too long
            mHandler.postDelayed(() -> {
                mReadyToTap = true;
            }, READY_TO_TAP_MAX_DELAY_MS);
        }

        loadVideo();
    }

    private void displayFallbackView() {
        if (DEBUG) Log.d(TAG, "Showing the fallback view");
        findViewById(R.id.fallback_layout).setVisibility(View.VISIBLE);
        findViewById(R.id.video_layout).setVisibility(View.GONE);
    }

    private void displayVideoView() {
        if (DEBUG) Log.d(TAG, "Showing the video view");
        findViewById(R.id.video_layout).setVisibility(View.VISIBLE);
        findViewById(R.id.fallback_layout).setVisibility(View.GONE);
    }

    private void loadVideo() {
        // If the video is already downloaded, then use that and check for an update.
        // Otherwise check if the video is preloaded, if not download the video from the
        // specified url.
        boolean isVideoSet = false;
        if (new File(mDownloadPath).exists()) {
            if (DEBUG) Log.d(TAG, "Using the already existing video at " + mDownloadPath);
            setVideoPath(mDownloadPath);
            isVideoSet = true;
        } else if (mPreloadedVideoFile.exists()) {
            if (DEBUG) Log.d(TAG, "Using the preloaded video at " + mPreloadedVideoFile);
            setVideoPath(mPreloadedVideoFile.getPath());
            isVideoSet = true;
        }

        final String downloadUrl = getString(R.string.retail_demo_video_download_url);
        // If the download url is empty, then no need to start the download task.
        if (TextUtils.isEmpty(downloadUrl)) {
            if (!isVideoSet) {
                displayFallbackView();
            }
            return;
        }
        if (!checkIfDownloadingAllowed()) {
            if (DEBUG) Log.d(TAG, "Downloading not allowed, neither starting download nor checking"
                    + " for an update.");
            if (!isVideoSet) {
                displayFallbackView();
            }
            return;
        }
        new DownloadVideoTask(this, mDownloadPath, mPreloadedVideoFile, this).run();
    }

    private boolean checkIfDownloadingAllowed() {
        final long lastRealElapsedTime = DataReaderWriter.getElapsedRealTime(this);
        final long realElapsedTime = SystemClock.elapsedRealtime();
        // We need to download the video atmost once after every boot.
        if (lastRealElapsedTime == 0 || realElapsedTime < lastRealElapsedTime) {
            DataReaderWriter.setElapsedRealTime(this,
                    realElapsedTime + REAL_ELAPSED_TIME_OFFSET_MS);
            return true;
        }
        return false;
    }

    @Override
    public void onFileDownloaded(final String filePath) {
        mUsingDownloadedVideo = true;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                setVideoPath(filePath);
            }
        });
    }

    @Override
    public void onError() {
        displayFallbackView();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mReadyToTap && getSystemService(UserManager.class).isDemoUser()) {
            disableSelf();
        }
        return true;
    }

    private void disableSelf() {
        final String componentName = getString(R.string.demo_overlay_app_component);
        if (!TextUtils.isEmpty(componentName)) {
            ComponentName component = ComponentName.unflattenFromString(componentName);
            if (component != null) {
                Intent intent = new Intent();
                intent.setComponent(component);
                ResolveInfo resolveInfo = getPackageManager().resolveService(intent, 0);
                if (resolveInfo != null) {
                    startService(intent);
                } else {
                    resolveInfo = getPackageManager().resolveActivity(intent,
                            PackageManager.MATCH_DEFAULT_ONLY);
                    if (resolveInfo != null) {
                        startActivity(intent);
                    } else {
                        Log.w(TAG, "Component " + componentName + " cannot be resolved");
                    }
                }
            }
        }
        getPackageManager().setComponentEnabledSetting(getComponentName(),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
    }

    @Override
    public void onPause() {
        if (mVideoView != null) {
            mVideoView.pause();
        }
        // If power key is pressed to turn screen off, turn screen back on
        if (!mPowerManager.isInteractive()) {
            forceTurnOnScreen();
        }
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        // Resume video playing
        if (mVideoView != null) {
            mVideoView.start();
        }
    }

    @Override
    protected void onDestroy() {
        if (mSettingsObserver != null) {
            mSettingsObserver.unregister();
            mSettingsObserver = null;
        }
        super.onDestroy();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        if (hasFocus) {
            // Make view fullscreen.
            // And since flags SYSTEM_UI_FLAG_HIDE_NAVIGATION and SYSTEM_UI_FLAG_HIDE_NAVIGATION
            // might get cleared on user interaction, we do this here.
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                            | View.STATUS_BAR_DISABLE_BACK);
        }
    }

    private void setVideoPath(String videoPath) {
        // Load the video from resource
        try {
            mVideoView.setVideoPath(videoPath);
            displayVideoView();
        } catch (Exception e) {
            Log.e(TAG, "Exception setting video uri! " + e.getMessage());
            displayFallbackView();
        }
    }

    private void forceTurnOnScreen() {
        final PowerManager.WakeLock wakeLock = mPowerManager.newWakeLock(
                PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
        wakeLock.acquire();
        // Device woken up, release the wake-lock
        wakeLock.release();
    }

    private class SettingsObserver extends ContentObserver {
        private final Uri mDemoModeSetupComplete = Settings.Secure.getUriFor(
                Settings.Secure.DEMO_USER_SETUP_COMPLETE);

        SettingsObserver() {
            super(mHandler);
        }

        void register() {
            ContentResolver cr = getContentResolver();
            cr.registerContentObserver(mDemoModeSetupComplete, false, this);
        }

        void unregister() {
            getContentResolver().unregisterContentObserver(this);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            if (mDemoModeSetupComplete.equals(uri)) {
                mReadyToTap = true;
            }
        }
    }

    private boolean isUserSetupComplete() {
        return "1".equals(Settings.Secure.getString(getContentResolver(),
                Settings.Secure.DEMO_USER_SETUP_COMPLETE));
    }
}
