/*
 * Copyright (C) 2009 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.browser;

import com.android.browser.preferences.WebsiteSettingsFragment;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.StatFs;
import android.preference.PreferenceActivity;
import android.util.Log;
import android.webkit.WebStorage;

import java.io.File;


/**
 * Package level class for managing the disk size consumed by the WebDatabase
 * and ApplicationCaches APIs (henceforth called Web storage).
 *
 * Currently, the situation on the WebKit side is as follows:
 *  - WebDatabase enforces a quota for each origin.
 *  - Session/LocalStorage do not enforce any disk limits.
 *  - ApplicationCaches enforces a maximum size for all origins.
 *
 * The WebStorageSizeManager maintains a global limit for the disk space
 * consumed by the WebDatabase and ApplicationCaches. As soon as WebKit will
 * have a limit for Session/LocalStorage, this class will manage the space used
 * by those APIs as well.
 *
 * The global limit is computed as a function of the size of the partition where
 * these APIs store their data (they must store it on the same partition for
 * this to work) and the size of the available space on that partition.
 * The global limit is not subject to user configuration but we do provide
 * a debug-only setting.
 * TODO(andreip): implement the debug setting.
 *
 * The size of the disk space used for Web storage is initially divided between
 * WebDatabase and ApplicationCaches as follows:
 *
 * 75% for WebDatabase
 * 25% for ApplicationCaches
 *
 * When an origin's database usage reaches its current quota, WebKit invokes
 * the following callback function:
 * - exceededDatabaseQuota(Frame* frame, const String& database_name);
 * Note that the default quota for a new origin is 0, so we will receive the
 * 'exceededDatabaseQuota' callback before a new origin gets the chance to
 * create its first database.
 *
 * When the total ApplicationCaches usage reaches its current quota, WebKit
 * invokes the following callback function:
 * - void reachedMaxAppCacheSize(int64_t spaceNeeded);
 *
 * The WebStorageSizeManager's main job is to respond to the above two callbacks
 * by inspecting the amount of unused Web storage quota (i.e. global limit -
 * sum of all other origins' quota) and deciding if a quota increase for the
 * out-of-space origin is allowed or not.
 *
 * The default quota for an origin is its estimated size. If we cannot satisfy
 * the estimated size, then WebCore will not create the database.
 * Quota increases are done in steps, where the increase step is
 * min(QUOTA_INCREASE_STEP, unused_quota).
 *
 * When all the Web storage space is used, the WebStorageSizeManager creates
 * a system notification that will guide the user to the WebSettings UI. There,
 * the user can free some of the Web storage space by deleting all the data used
 * by an origin.
 */
public class WebStorageSizeManager {
    // Logging flags.
    private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
    private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
    private final static String LOGTAG = "browser";
    // The default quota value for an origin.
    public final static long ORIGIN_DEFAULT_QUOTA = 3 * 1024 * 1024;  // 3MB
    // The default value for quota increases.
    public final static long QUOTA_INCREASE_STEP = 1 * 1024 * 1024;  // 1MB
    // Extra padding space for appcache maximum size increases. This is needed
    // because WebKit sends us an estimate of the amount of space needed
    // but this estimate may, currently, be slightly less than what is actually
    // needed. We therefore add some 'padding'.
    // TODO(andreip): fix this in WebKit.
    public final static long APPCACHE_MAXSIZE_PADDING = 512 * 1024; // 512KB
    // The system status bar notification id.
    private final static int OUT_OF_SPACE_ID = 1;
    // The time of the last out of space notification
    private static long mLastOutOfSpaceNotificationTime = -1;
    // Delay between two notification in ms
    private final static long NOTIFICATION_INTERVAL = 5 * 60 * 1000;
    // Delay in ms used when resetting the notification time
    private final static long RESET_NOTIFICATION_INTERVAL = 3 * 1000;
    // The application context.
    private final Context mContext;
    // The global Web storage limit.
    private final long mGlobalLimit;
    // The maximum size of the application cache file.
    private long mAppCacheMaxSize;

    /**
     * Interface used by the WebStorageSizeManager to obtain information
     * about the underlying file system. This functionality is separated
     * into its own interface mainly for testing purposes.
     */
    public interface DiskInfo {
        /**
         * @return the size of the free space in the file system.
         */
        public long getFreeSpaceSizeBytes();

        /**
         * @return the total size of the file system.
         */
        public long getTotalSizeBytes();
    };

    private DiskInfo mDiskInfo;
    // For convenience, we provide a DiskInfo implementation that uses StatFs.
    public static class StatFsDiskInfo implements DiskInfo {
        private StatFs mFs;

        public StatFsDiskInfo(String path) {
            mFs = new StatFs(path);
        }

        public long getFreeSpaceSizeBytes() {
            return (long)(mFs.getAvailableBlocks()) * mFs.getBlockSize();
        }

        public long getTotalSizeBytes() {
            return (long)(mFs.getBlockCount()) * mFs.getBlockSize();
        }
    };

    /**
     * Interface used by the WebStorageSizeManager to obtain information
     * about the appcache file. This functionality is separated into its own
     * interface mainly for testing purposes.
     */
    public interface AppCacheInfo {
        /**
         * @return the current size of the appcache file.
         */
        public long getAppCacheSizeBytes();
    };

    // For convenience, we provide an AppCacheInfo implementation.
    public static class WebKitAppCacheInfo implements AppCacheInfo {
        // The name of the application cache file. Keep in sync with
        // WebCore/loader/appcache/ApplicationCacheStorage.cpp
        private final static String APPCACHE_FILE = "ApplicationCache.db";
        private String mAppCachePath;

        public WebKitAppCacheInfo(String path) {
            mAppCachePath = path;
        }

        public long getAppCacheSizeBytes() {
            File file = new File(mAppCachePath
                    + File.separator
                    + APPCACHE_FILE);
            return file.length();
        }
    };

    /**
     * Public ctor
     * @param ctx is the application context
     * @param diskInfo is the DiskInfo instance used to query the file system.
     * @param appCacheInfo is the AppCacheInfo used to query info about the
     * appcache file.
     */
    public WebStorageSizeManager(Context ctx, DiskInfo diskInfo,
            AppCacheInfo appCacheInfo) {
        mContext = ctx.getApplicationContext();
        mDiskInfo = diskInfo;
        mGlobalLimit = getGlobalLimit();
        // The initial max size of the app cache is either 25% of the global
        // limit or the current size of the app cache file, whichever is bigger.
        mAppCacheMaxSize = Math.max(mGlobalLimit / 4,
                appCacheInfo.getAppCacheSizeBytes());
    }

    /**
     * Returns the maximum size of the application cache.
     */
    public long getAppCacheMaxSize() {
        return mAppCacheMaxSize;
    }

    /**
     * The origin has exceeded its database quota.
     * @param url the URL that exceeded the quota
     * @param databaseIdentifier the identifier of the database on
     *     which the transaction that caused the quota overflow was run
     * @param currentQuota the current quota for the origin.
     * @param estimatedSize the estimated size of a new database, or 0 if
     *     this has been invoked in response to an existing database
     *     overflowing its quota.
     * @param totalUsedQuota is the sum of all origins' quota.
     * @param quotaUpdater The callback to run when a decision to allow or
     *     deny quota has been made. Don't forget to call this!
     */
    public void onExceededDatabaseQuota(String url,
        String databaseIdentifier, long currentQuota, long estimatedSize,
        long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
        if(LOGV_ENABLED) {
            Log.v(LOGTAG,
                  "Received onExceededDatabaseQuota for "
                  + url
                  + ":"
                  + databaseIdentifier
                  + "(current quota: "
                  + currentQuota
                  + ", total used quota: "
                  + totalUsedQuota
                  + ")");
        }
        long totalUnusedQuota = mGlobalLimit - totalUsedQuota - mAppCacheMaxSize;

        if (totalUnusedQuota <= 0) {
            // There definitely isn't any more space. Fire notifications
            // if needed and exit.
            if (totalUsedQuota > 0) {
                // We only fire the notification if there are some other websites
                // using some of the quota. This avoids the degenerate case where
                // the first ever website to use Web storage tries to use more
                // data than it is actually available. In such a case, showing
                // the notification would not help at all since there is nothing
                // the user can do.
                scheduleOutOfSpaceNotification();
            }
            quotaUpdater.updateQuota(currentQuota);
            if(LOGV_ENABLED) {
                Log.v(LOGTAG, "onExceededDatabaseQuota: out of space.");
            }
            return;
        }

        // We have some space inside mGlobalLimit.
        long newOriginQuota = currentQuota;
        if (newOriginQuota == 0) {
            // This is a new origin, give it the size it asked for if possible.
            // If we cannot satisfy the estimatedSize, we should return 0 as
            // returning a value less that what the site requested will lead
            // to webcore not creating the database.
            if (totalUnusedQuota >= estimatedSize) {
                newOriginQuota = estimatedSize;
            } else {
                if (LOGV_ENABLED) {
                    Log.v(LOGTAG,
                            "onExceededDatabaseQuota: Unable to satisfy" +
                            " estimatedSize for the new database " +
                            " (estimatedSize: " + estimatedSize +
                            ", unused quota: " + totalUnusedQuota);
                }
                newOriginQuota = 0;
            }
        } else {
            // This is an origin we have seen before. It wants a quota
            // increase. There are two circumstances: either the origin
            // is creating a new database or it has overflowed an existing database.

            // Increase the quota. If estimatedSize == 0, then this is a quota overflow
            // rather than the creation of a new database.
            long quotaIncrease = estimatedSize == 0 ?
                    Math.min(QUOTA_INCREASE_STEP, totalUnusedQuota) :
                    estimatedSize;
            newOriginQuota += quotaIncrease;

            if (quotaIncrease > totalUnusedQuota) {
                // We can't fit, so deny quota.
                newOriginQuota = currentQuota;
            }
        }

        quotaUpdater.updateQuota(newOriginQuota);

        if(LOGV_ENABLED) {
            Log.v(LOGTAG, "onExceededDatabaseQuota set new quota to "
                    + newOriginQuota);
        }
    }

    /**
     * The Application Cache has exceeded its max size.
     * @param spaceNeeded is the amount of disk space that would be needed
     * in order for the last appcache operation to succeed.
     * @param totalUsedQuota is the sum of all origins' quota.
     * @param quotaUpdater A callback to inform the WebCore thread that a new
     * app cache size is available. This callback must always be executed at
     * some point to ensure that the sleeping WebCore thread is woken up.
     */
    public void onReachedMaxAppCacheSize(long spaceNeeded, long totalUsedQuota,
            WebStorage.QuotaUpdater quotaUpdater) {
        if(LOGV_ENABLED) {
            Log.v(LOGTAG, "Received onReachedMaxAppCacheSize with spaceNeeded "
                  + spaceNeeded + " bytes.");
        }

        long totalUnusedQuota = mGlobalLimit - totalUsedQuota - mAppCacheMaxSize;

        if (totalUnusedQuota < spaceNeeded + APPCACHE_MAXSIZE_PADDING) {
            // There definitely isn't any more space. Fire notifications
            // if needed and exit.
            if (totalUsedQuota > 0) {
                // We only fire the notification if there are some other websites
                // using some of the quota. This avoids the degenerate case where
                // the first ever website to use Web storage tries to use more
                // data than it is actually available. In such a case, showing
                // the notification would not help at all since there is nothing
                // the user can do.
                scheduleOutOfSpaceNotification();
            }
            quotaUpdater.updateQuota(0);
            if(LOGV_ENABLED) {
                Log.v(LOGTAG, "onReachedMaxAppCacheSize: out of space.");
            }
            return;
        }
        // There is enough space to accommodate spaceNeeded bytes.
        mAppCacheMaxSize += spaceNeeded + APPCACHE_MAXSIZE_PADDING;
        quotaUpdater.updateQuota(mAppCacheMaxSize);

        if(LOGV_ENABLED) {
            Log.v(LOGTAG, "onReachedMaxAppCacheSize set new max size to "
                    + mAppCacheMaxSize);
        }
    }

    // Reset the notification time; we use this iff the user
    // use clear all; we reset it to some time in the future instead
    // of just setting it to -1, as the clear all method is asynchronous
    public static void resetLastOutOfSpaceNotificationTime() {
        mLastOutOfSpaceNotificationTime = System.currentTimeMillis() -
            NOTIFICATION_INTERVAL + RESET_NOTIFICATION_INTERVAL;
    }

    // Computes the global limit as a function of the size of the data
    // partition and the amount of free space on that partition.
    private long getGlobalLimit() {
        long freeSpace = mDiskInfo.getFreeSpaceSizeBytes();
        long fileSystemSize = mDiskInfo.getTotalSizeBytes();
        return calculateGlobalLimit(fileSystemSize, freeSpace);
    }

    /*package*/ static long calculateGlobalLimit(long fileSystemSizeBytes,
            long freeSpaceBytes) {
        if (fileSystemSizeBytes <= 0
                || freeSpaceBytes <= 0
                || freeSpaceBytes > fileSystemSizeBytes) {
            return 0;
        }

        long fileSystemSizeRatio =
            2 << ((int) Math.floor(Math.log10(
                    fileSystemSizeBytes / (1024 * 1024))));
        long maxSizeBytes = (long) Math.min(Math.floor(
                fileSystemSizeBytes / fileSystemSizeRatio),
                Math.floor(freeSpaceBytes / 2));
        // Round maxSizeBytes up to a multiple of 1024KB (but only if
        // maxSizeBytes > 1MB).
        long maxSizeStepBytes = 1024 * 1024;
        if (maxSizeBytes < maxSizeStepBytes) {
            return 0;
        }
        long roundingExtra = maxSizeBytes % maxSizeStepBytes == 0 ? 0 : 1;
        return (maxSizeStepBytes
                * ((maxSizeBytes / maxSizeStepBytes) + roundingExtra));
    }

    // Schedules a system notification that takes the user to the WebSettings
    // activity when clicked.
    private void scheduleOutOfSpaceNotification() {
        if(LOGV_ENABLED) {
            Log.v(LOGTAG, "scheduleOutOfSpaceNotification called.");
        }
        if ((mLastOutOfSpaceNotificationTime == -1) ||
            (System.currentTimeMillis() - mLastOutOfSpaceNotificationTime > NOTIFICATION_INTERVAL)) {
            // setup the notification boilerplate.
            int icon = android.R.drawable.stat_sys_warning;
            CharSequence title = mContext.getString(
                    R.string.webstorage_outofspace_notification_title);
            CharSequence text = mContext.getString(
                    R.string.webstorage_outofspace_notification_text);
            long when = System.currentTimeMillis();
            Intent intent = new Intent(mContext, BrowserPreferencesPage.class);
            intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
                    WebsiteSettingsFragment.class.getName());
            PendingIntent contentIntent =
                PendingIntent.getActivity(mContext, 0, intent, 0);
            Notification notification = new Notification(icon, title, when);
            notification.setLatestEventInfo(mContext, title, text, contentIntent);
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            // Fire away.
            String ns = Context.NOTIFICATION_SERVICE;
            NotificationManager mgr =
                (NotificationManager) mContext.getSystemService(ns);
            if (mgr != null) {
                mLastOutOfSpaceNotificationTime = System.currentTimeMillis();
                mgr.notify(OUT_OF_SPACE_ID, notification);
            }
        }
    }
}
