// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.safety_check;

import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
import android.text.format.DateUtils;
import android.view.View;

import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;

import org.chromium.base.BuildConfig;
import org.chromium.base.Callback;
import org.chromium.base.ContextUtils;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.password_check.BulkLeakCheckServiceState;
import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
import org.chromium.chrome.browser.safe_browsing.settings.SecuritySettingsFragment;
import org.chromium.chrome.browser.safety_check.SafetyCheckBridge.SafetyCheckCommonObserver;
import org.chromium.chrome.browser.safety_check.SafetyCheckProperties.PasswordsState;
import org.chromium.chrome.browser.safety_check.SafetyCheckProperties.SafeBrowsingState;
import org.chromium.chrome.browser.safety_check.SafetyCheckProperties.UpdatesState;
import org.chromium.chrome.browser.settings.SettingsLauncher;
import org.chromium.content_public.common.ContentUrlConstants;
import org.chromium.ui.modelutil.PropertyModel;

import java.lang.ref.WeakReference;

class SafetyCheckMediator implements SafetyCheckCommonObserver {
    /** The minimal amount of time to show the checking state. */
    private static final int CHECKING_MIN_DURATION_MS = 1000;
    /** Time after which the null-states will be shown: 10 minutes. */
    private static final long RESET_TO_NULL_AFTER_MS = 10 * DateUtils.MINUTE_IN_MILLIS;

    /** Bridge to the C++ side for the Safe Browsing and passwords checks. */
    private SafetyCheckBridge mSafetyCheckBridge;
    /** Model representing the current state of the checks. */
    private PropertyModel mModel;
    /** Client to interact with Omaha for the updates check. */
    private SafetyCheckUpdatesDelegate mUpdatesClient;
    /** Callbacks and related objects to show the checking state for at least 1 second. */
    private Handler mHandler;
    private Runnable mRunnablePasswords;
    private Runnable mRunnableSafeBrowsing;
    private Runnable mRunnableUpdates;
    private long mCheckStartTime = -1;

    private final SharedPreferencesManager mPreferenceManager;

    /**
     * Callback that gets invoked once the result of the updates check is available. Not inlined
     * because a {@link WeakReference} needs to be passed (the check is asynchronous).
     */
    private final Callback<Integer> mUpdatesCheckCallback = (status) -> {
        mRunnableUpdates = () -> {
            if (mModel != null) {
                mModel.set(SafetyCheckProperties.UPDATES_STATE, status);
            }
        };
        if (mHandler != null) {
            // Show the checking state for at least 1 second for a smoother UX.
            mHandler.postDelayed(mRunnableUpdates, getModelUpdateDelay());
        }
    };

    /**
     * Creates a new instance given a model, an updates client, and a settings launcher.
     *
     * @param model A model instance.
     * @param client An updates client.
     * @param settingsLauncher An instance of the {@link SettingsLauncher} implementation.
     */
    public SafetyCheckMediator(PropertyModel model, SafetyCheckUpdatesDelegate client,
            SettingsLauncher settingsLauncher) {
        this(model, client, settingsLauncher, null, new Handler());
        // Have to initialize this after the constructor call, since a "this" instance is needed.
        mSafetyCheckBridge = new SafetyCheckBridge(SafetyCheckMediator.this);
        // Determine and set the initial state.
        setInitialState();
    }

    @VisibleForTesting
    SafetyCheckMediator(PropertyModel model, SafetyCheckUpdatesDelegate client,
            SettingsLauncher settingsLauncher, SafetyCheckBridge bridge, Handler handler) {
        mModel = model;
        mUpdatesClient = client;
        mSafetyCheckBridge = bridge;
        mHandler = handler;
        mPreferenceManager = SharedPreferencesManager.getInstance();
        // Set the listener for clicking the updates element.
        mModel.set(SafetyCheckProperties.UPDATES_CLICK_LISTENER,
                (Preference.OnPreferenceClickListener) (p) -> {
                    if (!BuildConfig.IS_CHROME_BRANDED) {
                        return true;
                    }
                    String chromeAppId = ContextUtils.getApplicationContext().getPackageName();
                    // Open the Play Store page for the installed Chrome channel.
                    p.getContext().startActivity(new Intent(Intent.ACTION_VIEW,
                            Uri.parse(ContentUrlConstants.PLAY_STORE_URL_PREFIX + chromeAppId)));
                    return true;
                });
        // Set the listener for clicking the Safe Browsing element.
        mModel.set(SafetyCheckProperties.SAFE_BROWSING_CLICK_LISTENER,
                (Preference.OnPreferenceClickListener) (p) -> {
                    String safeBrowsingSettingsClassName;
                    if (ChromeFeatureList.isEnabled(
                                ChromeFeatureList.SAFE_BROWSING_SECURITY_SECTION_UI)) {
                        // Open the Security settings since the flag for them is enabled.
                        safeBrowsingSettingsClassName = SecuritySettingsFragment.class.getName();
                    } else {
                        // Open the Sync and Services settings.
                        // TODO(crbug.com/1070620): replace the hardcoded class name with an import
                        // and ".class.getName()" once SyncAndServicesSettings is moved out of
                        // //chrome/android.
                        safeBrowsingSettingsClassName =
                                "org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings";
                    }
                    p.getContext().startActivity(settingsLauncher.createSettingsActivityIntent(
                            p.getContext(), safeBrowsingSettingsClassName));
                    return true;
                });
        // Set the listener for clicking the passwords element.
        mModel.set(SafetyCheckProperties.PASSWORDS_CLICK_LISTENER,
                (Preference.OnPreferenceClickListener) (p) -> {
                    // Open the Passwords settings.
                    // TODO(crbug.com/1070620): replace the hardcoded class name with an import and
                    // ".class.getName()" once PasswordSettings is moved out of //chrome/android.
                    p.getContext().startActivity(settingsLauncher.createSettingsActivityIntent(
                            p.getContext(),
                            "org.chromium.chrome.browser.password_manager.settings.PasswordSettings"));
                    return true;
                });
        // Set the listener for clicking the Check button.
        mModel.set(SafetyCheckProperties.SAFETY_CHECK_BUTTON_CLICK_LISTENER,
                (View.OnClickListener) (v) -> performSafetyCheck());
        // Get the timestamp of the last run.
        mModel.set(SafetyCheckProperties.LAST_RUN_TIMESTAMP,
                mPreferenceManager.readLong(
                        ChromePreferenceKeys.SETTINGS_SAFETY_CHECK_LAST_RUN_TIMESTAMP, 0));
        if (mSafetyCheckBridge != null) {
            // Determine and set the initial state.
            setInitialState();
        }
    }

    /**
     * Determines the initial state to show, triggering any fast checks if necessary based on the
     * last run timestamp.
     */
    public void setInitialState() {
        long currentTime = System.currentTimeMillis();
        long lastRun = mPreferenceManager.readLong(
                ChromePreferenceKeys.SETTINGS_SAFETY_CHECK_LAST_RUN_TIMESTAMP, 0);
        // Always show the passwords unsafe state.
        if (mSafetyCheckBridge.getNumberOfPasswordLeaksFromLastCheck() != 0) {
            mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.COMPROMISED_EXIST);
        }
        if (currentTime - lastRun < RESET_TO_NULL_AFTER_MS) {
            // Show the passwords safe state
            if (!mSafetyCheckBridge.savedPasswordsExist()) {
                mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.NO_PASSWORDS);
            } else if (mSafetyCheckBridge.getNumberOfPasswordLeaksFromLastCheck() == 0) {
                mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.SAFE);
            }
            // Rerun the updates and Safe Browsing checks.
            mModel.set(SafetyCheckProperties.SAFE_BROWSING_STATE, SafeBrowsingState.CHECKING);
            mModel.set(SafetyCheckProperties.UPDATES_STATE, UpdatesState.CHECKING);
            mSafetyCheckBridge.checkSafeBrowsing();
            mUpdatesClient.checkForUpdates(new WeakReference(mUpdatesCheckCallback));
        } else {
            // The unsafe state was already set above, so only set to unchecked if it is safe.
            if (mSafetyCheckBridge.getNumberOfPasswordLeaksFromLastCheck() == 0) {
                mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.UNCHECKED);
            }
            mModel.set(SafetyCheckProperties.SAFE_BROWSING_STATE, SafeBrowsingState.UNCHECKED);
            mModel.set(SafetyCheckProperties.UPDATES_STATE, UpdatesState.UNCHECKED);
        }
    }

    /** Triggers all safety check child checks. */
    public void performSafetyCheck() {
        // Cancel pending delayed show callbacks if a new check is starting while any existing
        // elements are pending.
        cancelCallbacks();
        // Record the start time for tracking 1 second checking delay in the UI.
        mCheckStartTime = SystemClock.elapsedRealtime();
        // Record the absolute start time for showing when the last Safety check was performed.
        long currentTime = System.currentTimeMillis();
        mModel.set(SafetyCheckProperties.LAST_RUN_TIMESTAMP, currentTime);
        mPreferenceManager.writeLong(
                ChromePreferenceKeys.SETTINGS_SAFETY_CHECK_LAST_RUN_TIMESTAMP, currentTime);
        // Increment the stored number of Safety check starts.
        mPreferenceManager.incrementInt(ChromePreferenceKeys.SETTINGS_SAFETY_CHECK_RUN_COUNTER);
        // Set the checking state for all elements.
        mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.CHECKING);
        mModel.set(SafetyCheckProperties.SAFE_BROWSING_STATE, SafeBrowsingState.CHECKING);
        mModel.set(SafetyCheckProperties.UPDATES_STATE, UpdatesState.CHECKING);
        // Start all the checks.
        mSafetyCheckBridge.checkSafeBrowsing();
        mSafetyCheckBridge.checkPasswords();
        mUpdatesClient.checkForUpdates(new WeakReference(mUpdatesCheckCallback));
    }

    /**
     * Gets invoked once the Safe Browsing check is completed.
     *
     * @param status SafetyCheck::SafeBrowsingStatus enum value representing the Safe Browsing state
     *     (see //components/safety_check/safety_check.h).
     */
    @Override
    public void onSafeBrowsingCheckResult(@SafeBrowsingStatus int status) {
        mRunnableSafeBrowsing = () -> {
            mModel.set(SafetyCheckProperties.SAFE_BROWSING_STATE,
                    SafetyCheckProperties.safeBrowsingStateFromNative(status));
        };
        // Show the checking state for at least 1 second for a smoother UX.
        mHandler.postDelayed(mRunnableSafeBrowsing, getModelUpdateDelay());
    }

    /**
     * Gets invoked by the C++ code every time another credential is checked.
     *
     * @param checked Number of passwords already checked.
     * @param total Total number of passwords to check.
     */
    @Override
    public void onPasswordCheckCredentialDone(int checked, int total) {}

    /**
     * Gets invoked by the C++ code when the status of the password check changes.
     *
     * @param state BulkLeakCheckService::State enum value representing the state (see
     *     //components/password_manager/core/browser/bulk_leak_check_service_interface.h).
     */
    @Override
    public void onPasswordCheckStateChange(@BulkLeakCheckServiceState int state) {
        if (state == BulkLeakCheckServiceState.RUNNING) {
            return;
        }
        mSafetyCheckBridge.stopObservingPasswordsCheck();
        mRunnablePasswords = () -> {
            // Handle the error states.
            if (state != BulkLeakCheckServiceState.IDLE) {
                mModel.set(SafetyCheckProperties.PASSWORDS_STATE,
                        SafetyCheckProperties.passwordsStatefromErrorState(state));
                return;
            }
            // Non-error state depends on whether there are any passwords saved and/or leaked.
            if (!mSafetyCheckBridge.savedPasswordsExist()) {
                mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.NO_PASSWORDS);
            } else if (mSafetyCheckBridge.getNumberOfPasswordLeaksFromLastCheck() == 0) {
                mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.SAFE);
            } else {
                mModel.set(SafetyCheckProperties.PASSWORDS_STATE, PasswordsState.COMPROMISED_EXIST);
            }
        };
        // Show the checking state for at least 1 second for a smoother UX.
        mHandler.postDelayed(mRunnablePasswords, getModelUpdateDelay());
    }

    /** Cancels any pending callbacks and registered observers.  */
    public void destroy() {
        cancelCallbacks();
        mSafetyCheckBridge.destroy();
        mSafetyCheckBridge = null;
        mUpdatesClient = null;
        mModel = null;
        mHandler = null;
    }

    /** Cancels any delayed show callbacks. */
    private void cancelCallbacks() {
        if (mRunnablePasswords != null) {
            mHandler.removeCallbacks(mRunnablePasswords);
            mRunnablePasswords = null;
        }
        if (mRunnableSafeBrowsing != null) {
            mHandler.removeCallbacks(mRunnableSafeBrowsing);
            mRunnableSafeBrowsing = null;
        }
        if (mRunnableUpdates != null) {
            mHandler.removeCallbacks(mRunnableUpdates);
            mRunnableUpdates = null;
        }
    }

    /**
     * @return The delay in ms for updating the model in the running state.
     */
    private long getModelUpdateDelay() {
        return Math.max(
                0, mCheckStartTime + CHECKING_MIN_DURATION_MS - SystemClock.elapsedRealtime());
    }
}
