// Copyright 2015 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.webapps;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.AsyncTask;

import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.ShortcutSource;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.content_public.common.ScreenOrientationValues;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Stores data about an installed web app. Uses SharedPreferences to persist the data to disk.
 * This class must only be accessed via {@link WebappRegistry}, which is used to register and keep
 * track of web app data known to Chrome.
 */
public class WebappDataStorage {

    static final String SHARED_PREFS_FILE_PREFIX = "webapp_";
    static final String KEY_SPLASH_ICON = "splash_icon";
    static final String KEY_LAST_USED = "last_used";
    static final String KEY_URL = "url";
    static final String KEY_SCOPE = "scope";
    static final String KEY_ICON = "icon";
    static final String KEY_NAME = "name";
    static final String KEY_SHORT_NAME = "short_name";
    static final String KEY_ORIENTATION = "orientation";
    static final String KEY_THEME_COLOR = "theme_color";
    static final String KEY_BACKGROUND_COLOR = "background_color";
    static final String KEY_SOURCE = "source";
    static final String KEY_ACTION = "action";
    static final String KEY_IS_ICON_GENERATED = "is_icon_generated";
    static final String KEY_VERSION = "version";

    // Unset/invalid constants for last used times and URLs. 0 is used as the null last
    // used time as WebappRegistry assumes that this is always a valid timestamp.
    static final long LAST_USED_UNSET = 0;
    static final long LAST_USED_INVALID = -1;
    static final String URL_INVALID = "";
    static final int VERSION_INVALID = 0;

    // We use a heuristic to determine whether a web app is still installed on the home screen, as
    // there is no way to do so directly. Any web app which has been opened in the last ten days
    // is considered to be still on the home screen.
    static final long WEBAPP_LAST_OPEN_MAX_TIME = TimeUnit.DAYS.toMillis(10L);

    private static Clock sClock = new Clock();
    private static Factory sFactory = new Factory();

    private final String mId;
    private final SharedPreferences mPreferences;

    /**
     * Opens an instance of WebappDataStorage for the web app specified. Must not be run on the UI
     * thread.
     * @param context  The context to open the SharedPreferences.
     * @param webappId The ID of the web app which is being opened.
     */
    static WebappDataStorage open(final Context context, final String webappId) {
        final WebappDataStorage storage = sFactory.create(context, webappId);
        if (storage.getLastUsedTime() == LAST_USED_INVALID) {
            // If the last used time is invalid then ensure that there is no data in the
            // WebappDataStorage which needs to be cleaned up.
            assert storage.getAllData().isEmpty();
        }
        return storage;
    }

    /**
     * Asynchronously retrieves the time which this WebappDataStorage was last opened. Used in
     * testing.
     * @param context  The context to read the SharedPreferences file.
     * @param webappId The ID of the web app the used time is being read for.
     * @param callback Called when the last used time has been retrieved.
     */
    @VisibleForTesting
    public static void getLastUsedTime(final Context context, final String webappId,
            final FetchCallback<Long> callback) {
        new AsyncTask<Void, Void, Long>() {
            @Override
            protected final Long doInBackground(Void... nothing) {
                long lastUsed = new WebappDataStorage(context.getApplicationContext(), webappId)
                        .getLastUsedTime();
                assert lastUsed != LAST_USED_INVALID;
                return lastUsed;
            }

            @Override
            protected final void onPostExecute(Long lastUsed) {
                assert callback != null;
                callback.onDataRetrieved(lastUsed);
            }
        }.execute();
    }

    /**
     * Asynchronously retrieves the scope stored in this WebappDataStorage. The scope is the URL
     * over which the web app data is applied to. Used in testing.
     * @param context  The context to read the SharedPreferences file.
     * @param webappId The ID of the web app the used time is being read for.
     * @param callback Called when the scope has been retrieved.
     */
    @VisibleForTesting
    public static void getScope(final Context context, final String webappId,
            final FetchCallback<String> callback) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected final String doInBackground(Void... nothing) {
                return new WebappDataStorage(context.getApplicationContext(), webappId).getScope();
            }

            @Override
            protected final void onPostExecute(String scope) {
                assert callback != null;
                callback.onDataRetrieved(scope);
            }
        }.execute();
    }

    /**
     * Asynchronously retrieves the URL stored in this WebappDataStorage. Used in testing.
     * @param context  The context to read the SharedPreferences file.
     * @param webappId The ID of the web app the used time is being read for.
     * @param callback Called when the URL has been retrieved.
     */
    @VisibleForTesting
    public static void getUrl(final Context context, final String webappId,
            final FetchCallback<String> callback) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected final String doInBackground(Void... nothing) {
                return new WebappDataStorage(context.getApplicationContext(), webappId).getUrl();
            }

            @Override
            protected final void onPostExecute(String url) {
                assert callback != null;
                callback.onDataRetrieved(url);
            }
        }.execute();
    }

    /**
     * Deletes the data for a web app by clearing all the information inside the SharedPreferences
     * file. This does NOT delete the file itself but the file is left empty.
     * @param context  The context to read the SharedPreferences file.
     * @param webappId The ID of the web app being deleted.
     */
    static void deleteDataForWebapp(final Context context, final String webappId) {
        assert !ThreadUtils.runningOnUiThread();
        openSharedPreferences(context, webappId).edit().clear().apply();
    }

    /**
     * Deletes the URL and scope, and sets last used time to 0 in SharedPreferences.
     * This does not remove the stored splash screen image (if any) for the app.
     * @param context  The context to read the SharedPreferences file.
     * @param webappId The ID of the web app for which history is being cleared.
     */
    static void clearHistory(final Context context, final String webappId) {
        assert !ThreadUtils.runningOnUiThread();
        SharedPreferences.Editor editor = openSharedPreferences(context, webappId).edit();

        // The last used time is set to 0 to ensure that a valid value is always present.
        // If the web app is not launched prior to the next cleanup, then its remaining data will be
        // removed. Otherwise, the next launch from home screen will update the last used time.
        editor.putLong(KEY_LAST_USED, LAST_USED_UNSET);
        editor.remove(KEY_URL);
        editor.remove(KEY_SCOPE);
        editor.apply();
    }

    /**
     * Sets the clock used to get the current time.
     */
    @VisibleForTesting
    public static void setClockForTests(Clock clock) {
        sClock = clock;
    }

    /**
     * Sets the factory used to generate WebappDataStorage objects.
     */
    @VisibleForTesting
    public static void setFactoryForTests(Factory factory) {
        sFactory = factory;
    }

    private static SharedPreferences openSharedPreferences(Context context, String webappId) {
        return context.getApplicationContext().getSharedPreferences(
                SHARED_PREFS_FILE_PREFIX + webappId, Context.MODE_PRIVATE);
    }

    protected WebappDataStorage(Context context, String webappId) {
        mId = webappId;
        mPreferences = openSharedPreferences(context, webappId);
    }

    /**
     * Asynchronously retrieves the splash screen image associated with the current web app.
     * @param callback Called when the splash screen image has been retrieved.
     *                 The bitmap result may be null if no image was found.
     */
    public void getSplashScreenImage(final FetchCallback<Bitmap> callback) {
        new AsyncTask<Void, Void, Bitmap>() {
            @Override
            protected final Bitmap doInBackground(Void... nothing) {
                return ShortcutHelper.decodeBitmapFromString(
                        mPreferences.getString(KEY_SPLASH_ICON, null));
            }

            @Override
            protected final void onPostExecute(Bitmap result) {
                assert callback != null;
                callback.onDataRetrieved(result);
            }
        }.execute();
    }

    /**
     * Update the information associated with the web app with the specified data.
     * @param splashScreenImage The image which should be shown on the splash screen of the web app.
     */
    public void updateSplashScreenImage(final Bitmap splashScreenImage) {
        // Use an AsyncTask as this method is invoked on the UI thread from the callbacks leading to
        // ShortcutHelper.storeWebappSplashImage.
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected final Void doInBackground(Void... nothing) {
                String bitmap = ShortcutHelper.encodeBitmapAsString(splashScreenImage);
                mPreferences.edit().putString(KEY_SPLASH_ICON, bitmap).apply();
                return null;
            }
        }.execute();
    }

    /**
     * Creates and returns a web app launch intent from the data stored in this object. Must not be
     * called on the UI thread as a Bitmap is decoded from a String (a potentially expensive
     * operation).
     * @return The web app launch intent.
     */
    public Intent createWebappLaunchIntent() {
        assert !ThreadUtils.runningOnUiThread();
        // Assume that all of the data is invalid if the version isn't set, so return a null intent.
        int version = mPreferences.getInt(KEY_VERSION, VERSION_INVALID);
        if (version == VERSION_INVALID) return null;

        return ShortcutHelper.createWebappShortcutIntent(mId,
                mPreferences.getString(KEY_ACTION, null),
                mPreferences.getString(KEY_URL, null),
                mPreferences.getString(KEY_SCOPE, null),
                mPreferences.getString(KEY_NAME, null),
                mPreferences.getString(KEY_SHORT_NAME, null),
                ShortcutHelper.decodeBitmapFromString(
                        mPreferences.getString(KEY_ICON, null)), version,
                mPreferences.getInt(KEY_ORIENTATION, ScreenOrientationValues.DEFAULT),
                mPreferences.getLong(KEY_THEME_COLOR,
                        ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING),
                mPreferences.getLong(KEY_BACKGROUND_COLOR,
                        ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING),
                mPreferences.getBoolean(KEY_IS_ICON_GENERATED, false));
    }

    /**
     * Updates the data stored in this object to match that in the supplied intent.
     * @param shortcutIntent The intent to pull web app data from.
     */
    public void updateFromShortcutIntent(Intent shortcutIntent) {
        if (shortcutIntent == null) return;

        SharedPreferences.Editor editor = mPreferences.edit();
        boolean updated = false;

        // The URL and scope may have been deleted by the user clearing their history. Check whether
        // they are present, and update if necessary.
        String url = mPreferences.getString(KEY_URL, URL_INVALID);
        if (url.equals(URL_INVALID)) {
            url = IntentUtils.safeGetStringExtra(shortcutIntent, ShortcutHelper.EXTRA_URL);
            editor.putString(KEY_URL, url);
            updated = true;
        }

        if (mPreferences.getString(KEY_SCOPE, URL_INVALID).equals(URL_INVALID)) {
            String scope = IntentUtils.safeGetStringExtra(
                    shortcutIntent, ShortcutHelper.EXTRA_SCOPE);
            if (scope == null) {
                scope = ShortcutHelper.getScopeFromUrl(url);
            }
            editor.putString(KEY_SCOPE, scope);
            updated = true;
        }

        // For all other fields, assume that if the version key is present and equal to
        // ShortcutHelper.WEBAPP_SHORTCUT_VERSION, then all fields are present and do not need to be
        // updated. All fields except for the last used time, scope, and URL are either set or
        // cleared together.
        if (mPreferences.getInt(KEY_VERSION, VERSION_INVALID)
                != ShortcutHelper.WEBAPP_SHORTCUT_VERSION) {
            editor.putString(KEY_NAME, IntentUtils.safeGetStringExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_NAME));
            editor.putString(KEY_SHORT_NAME, IntentUtils.safeGetStringExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_SHORT_NAME));
            editor.putString(KEY_ICON, IntentUtils.safeGetStringExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_ICON));
            editor.putInt(KEY_VERSION, ShortcutHelper.WEBAPP_SHORTCUT_VERSION);
            editor.putInt(KEY_ORIENTATION, IntentUtils.safeGetIntExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_ORIENTATION,
                        ScreenOrientationValues.DEFAULT));
            editor.putLong(KEY_THEME_COLOR, IntentUtils.safeGetLongExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_THEME_COLOR,
                        ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING));
            editor.putLong(KEY_BACKGROUND_COLOR, IntentUtils.safeGetLongExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_BACKGROUND_COLOR,
                        ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING));
            editor.putBoolean(KEY_IS_ICON_GENERATED, IntentUtils.safeGetBooleanExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_IS_ICON_GENERATED, false));
            editor.putString(KEY_ACTION, shortcutIntent.getAction());
            editor.putInt(KEY_SOURCE, IntentUtils.safeGetIntExtra(
                        shortcutIntent, ShortcutHelper.EXTRA_SOURCE,
                        ShortcutSource.UNKNOWN));
            updated = true;
        }
        if (updated) editor.apply();
    }

    /**
     * Returns the scope stored in this object, or URL_INVALID if it is not stored.
     */
    String getScope() {
        return mPreferences.getString(KEY_SCOPE, URL_INVALID);
    }

    /**
     * Returns the URL stored in this object, or URL_INVALID if it is not stored.
     */
    String getUrl() {
        return mPreferences.getString(KEY_URL, URL_INVALID);
    }

    /**
     * Updates the last used time of this object.
     */
    void updateLastUsedTime() {
        mPreferences.edit().putLong(KEY_LAST_USED, sClock.currentTimeMillis()).apply();
    }

    /**
     * Returns the last used time of this object, or -1 if it is not stored.
     */
    long getLastUsedTime() {
        return mPreferences.getLong(KEY_LAST_USED, LAST_USED_INVALID);
    }

    /**
     * Returns true if this web app has been launched from home screen recently (within
     * WEBAPP_LAST_OPEN_MAX_TIME milliseconds).
     */
    public boolean wasLaunchedRecently() {
        // Registering the web app sets the last used time, so that counts as a 'launch'.
        return (sClock.currentTimeMillis() - getLastUsedTime() < WEBAPP_LAST_OPEN_MAX_TIME);
    }

    private Map<String, ?> getAllData() {
        return mPreferences.getAll();
    }

    /**
     * Called after data has been retrieved from storage.
     */
    public interface FetchCallback<T> {
        public void onDataRetrieved(T readObject);
    }

    /**
     * Factory used to generate WebappDataStorage objects.
     *
     * It is used in tests to override methods in WebappDataStorage and inject the mocked objects.
     */
    public static class Factory {

        /**
         * Generates a WebappDataStorage class for a specified web app.
         */
        public WebappDataStorage create(final Context context, final String webappId) {
            return new WebappDataStorage(context, webappId);
        }
    }

    /**
     * Clock used to generate the current time in millseconds for updating and setting last used
     * time.
     */
    public static class Clock {
        /**
         * Returns the current time in milliseconds.
         */
        public long currentTimeMillis() {
            return System.currentTimeMillis();
        }
    }
}
