/*
 * 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 android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.webkit.WebStorage;

/**
 * This is a series of unit tests for the WebStorageSizeManager class.
 *
 */
@MediumTest
public class WebStorageSizeManagerUnitTests extends AndroidTestCase {
    // Used for testing the out-of-space callbacks.
    private long mNewQuota;
    // Callback functor that sets a new quota in case of out-of-space scenarios.
    private class MockQuotaUpdater implements WebStorage.QuotaUpdater {
        public void updateQuota(long newQuota) {
            mNewQuota = newQuota;
        }
    }

    // Mock the DiskInfo.
    private class MockDiskInfo implements WebStorageSizeManager.DiskInfo {
        private long mFreeSize;
        private long mTotalSize;

        public long getFreeSpaceSizeBytes() {
            return mFreeSize;
        }

        public long getTotalSizeBytes() {
            return mTotalSize;
        }

        public void setFreeSpaceSizeBytes(long freeSize) {
            mFreeSize = freeSize;
        }

        public void setTotalSizeBytes(long totalSize) {
            mTotalSize = totalSize;
        }
    }

    // Mock the AppCacheInfo
    public class MockAppCacheInfo implements WebStorageSizeManager.AppCacheInfo {
        private long mAppCacheSize;

        public long getAppCacheSizeBytes() {
            return mAppCacheSize;
        }

        public void setAppCacheSizeBytes(long appCacheSize) {
            mAppCacheSize = appCacheSize;
        }
    }

    private MockQuotaUpdater mQuotaUpdater = new MockQuotaUpdater();
    private final MockDiskInfo mDiskInfo = new MockDiskInfo();
    private final MockAppCacheInfo mAppCacheInfo = new MockAppCacheInfo();
    // Utility for making size computations easier to read.
    private long bytes(double megabytes) {
        return (new Double(megabytes * 1024 * 1024)).longValue();
    }
    /**
     * Test the onExceededDatabaseQuota and onReachedMaxAppCacheSize callbacks
     */
    public void testCallbacks() {
        long totalUsedQuota = 0;
        final long quotaIncrease = WebStorageSizeManager.QUOTA_INCREASE_STEP;  // 1MB

        // We have 75 MB total, 24MB free so the global limit will be 12 MB.
        mDiskInfo.setTotalSizeBytes(bytes(75));
        mDiskInfo.setFreeSpaceSizeBytes(bytes(24));
        // We have an appcache file size of 0 MB.
        mAppCacheInfo.setAppCacheSizeBytes(0);
        // Create the manager.
        WebStorageSizeManager manager = new WebStorageSizeManager(getContext(), mDiskInfo,
                mAppCacheInfo);
        // We add origin 1.
        long origin1Quota = 0;
        long origin1EstimatedSize = bytes(3.5);
        manager.onExceededDatabaseQuota("1", "1", origin1Quota, origin1EstimatedSize, totalUsedQuota, mQuotaUpdater);
        assertEquals(origin1EstimatedSize, mNewQuota);
        origin1Quota = mNewQuota;
        totalUsedQuota += origin1Quota;

        // We add origin 2.
        long origin2Quota = 0;
        long origin2EstimatedSize = bytes(2.5);
        manager.onExceededDatabaseQuota("2", "2", origin2Quota, origin2EstimatedSize, totalUsedQuota, mQuotaUpdater);
        assertEquals(origin2EstimatedSize, mNewQuota);
        origin2Quota = mNewQuota;
        totalUsedQuota += origin2Quota;

        // Origin 1 runs out of space.
        manager.onExceededDatabaseQuota("1", "1", origin1Quota, 0, totalUsedQuota, mQuotaUpdater);
        assertEquals(origin1EstimatedSize + quotaIncrease, mNewQuota);
        totalUsedQuota -= origin1Quota;
        origin1Quota = mNewQuota;
        totalUsedQuota += origin1Quota;

        // Origin 2 runs out of space.
        manager.onExceededDatabaseQuota("2", "2", origin2Quota, 0, totalUsedQuota, mQuotaUpdater);
        assertEquals(origin2EstimatedSize + quotaIncrease, mNewQuota);
        totalUsedQuota -= origin2Quota;
        origin2Quota = mNewQuota;
        totalUsedQuota += origin2Quota;

        // We add origin 3. TotalUsedQuota is 8 (3.5 + 2.5 + 1 + 1). AppCacheMaxSize is 3 (12 / 4).
        // So we have 1 MB free.
        long origin3Quota = 0;
        long origin3EstimatedSize = bytes(5);
        manager.onExceededDatabaseQuota("3", "3", origin3Quota, origin3EstimatedSize, totalUsedQuota, mQuotaUpdater);
        assertEquals(0, mNewQuota);  // We cannot satisfy the estimatedSize
        origin3Quota = mNewQuota;
        totalUsedQuota += origin3Quota;

        // Origin 1 runs out of space again. It should increase it's quota to take the last 1MB.
        manager.onExceededDatabaseQuota("1", "1", origin1Quota, 0, totalUsedQuota, mQuotaUpdater);
        assertEquals(origin1Quota + quotaIncrease, mNewQuota);
        totalUsedQuota -= origin1Quota;
        origin1Quota = mNewQuota;
        totalUsedQuota += origin1Quota;

        // Origin 1 runs out of space again. It should inow fail to increase in size.
        manager.onExceededDatabaseQuota("1", "1", origin1Quota, 0, totalUsedQuota, mQuotaUpdater);
        assertEquals(origin1Quota, mNewQuota);

        // We try adding a new origin. Which will fail.
        manager.onExceededDatabaseQuota("4", "4", 0, bytes(1), totalUsedQuota, mQuotaUpdater);
        assertEquals(0, mNewQuota);

        // AppCache size increases to 2MB...
        mAppCacheInfo.setAppCacheSizeBytes(bytes(2));
        // ... and wants 2MB more. Fail.
        manager.onReachedMaxAppCacheSize(bytes(2), totalUsedQuota, mQuotaUpdater);
        assertEquals(0, mNewQuota);

        // The user nukes origin 2
        totalUsedQuota -= origin2Quota;
        origin2Quota = 0;
        // TotalUsedQuota is 5.5 (9 - 3.5). AppCacheMaxSize is 3. AppCacheSize is 2.
        // AppCache wants 1.5MB more
        manager.onReachedMaxAppCacheSize(bytes(1.5), totalUsedQuota, mQuotaUpdater);
        mAppCacheInfo.setAppCacheSizeBytes(mAppCacheInfo.getAppCacheSizeBytes() + bytes(2.5));
        assertEquals(mAppCacheInfo.getAppCacheSizeBytes(), mNewQuota - WebStorageSizeManager.APPCACHE_MAXSIZE_PADDING);

        // We try adding a new origin. This time we succeed.
        // TotalUsedQuota is 5.5. AppCacheMaxSize is 5.0. So we have 12 - 10.5 = 1.5 available.
        long origin4Quota = 0;
        long origin4EstimatedSize = bytes(1.5);
        manager.onExceededDatabaseQuota("4", "4", origin4Quota, origin4EstimatedSize, totalUsedQuota, mQuotaUpdater);
        assertEquals(bytes(1.5), mNewQuota);
        origin4Quota = mNewQuota;
        totalUsedQuota += origin4Quota;
    }
    /**
     * Test the application caches max size calculator.
     */
    public void testCalculateGlobalLimit() {
        long fileSystemSize = 78643200;  // 75 MB
        long freeSpaceSize = 25165824;  // 24 MB
        long maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(12582912, maxSize);  // 12MB

        fileSystemSize = 78643200;  // 75 MB
        freeSpaceSize = 60 * 1024 * 1024;  // 60MB
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(19922944, maxSize);  // 19MB

        fileSystemSize = 8589934592L;  // 8 GB
        freeSpaceSize = 4294967296L;  // 4 GB
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(536870912L, maxSize);  // 512 MB

        fileSystemSize = -14;
        freeSpaceSize = 21;
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(0, maxSize);

        fileSystemSize = 100;
        freeSpaceSize = 101;
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(0, maxSize);

        fileSystemSize = 3774873; // ~4.2 MB
        freeSpaceSize = 2560000;  // ~2.4 MB
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(2097152, maxSize);  // 2 MB

        fileSystemSize = 4404019; // ~4.2 MB
        freeSpaceSize = 3774873;  // ~3.6 MB
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(2097152, maxSize);  // 2 MB

        fileSystemSize = 4404019; // ~4.2 MB
        freeSpaceSize = 4404019;  // ~4.2 MB
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(3145728, maxSize);  // 3 MB

        fileSystemSize = 1048576; // 1 MB
        freeSpaceSize = 1048575;  // 1 MB - 1 byte
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(0, maxSize);

        fileSystemSize = 3774873; // ~3.6 MB
        freeSpaceSize = 2097151;  // 2 MB - 1 byte
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(0, maxSize);

        fileSystemSize = 3774873; // ~3.6 MB
        freeSpaceSize = 2097151;  // 2 MB
        maxSize = WebStorageSizeManager.calculateGlobalLimit(fileSystemSize, freeSpaceSize);
        assertEquals(0, maxSize);
    }

    public void testManyDatabasesOnOneOrigin() {
        // This test ensures that if an origin creates more than one database, the quota that is
        // assigned to the origin after the second creation is enough to satisfy all databases
        // under that origin.
        // See b/2417477.

        long totalUsedQuota = 0;
        mDiskInfo.setTotalSizeBytes(bytes(100));
        mDiskInfo.setFreeSpaceSizeBytes(bytes(100));
        // This should give us a storage area of 13MB, with 3.25MB for appcache and 9.75MB for
        // databases.
        assertEquals(bytes(13), WebStorageSizeManager.calculateGlobalLimit(
                mDiskInfo.getTotalSizeBytes(), mDiskInfo.getFreeSpaceSizeBytes()));

        // We have an appcache file size of 0 MB.
        mAppCacheInfo.setAppCacheSizeBytes(0);

        // Create the manager.
        WebStorageSizeManager manager = new WebStorageSizeManager(getContext(), mDiskInfo,
                mAppCacheInfo);

        // We add an origin.
        long originQuota = 0;
        long database1EstimatedSize = bytes(2);
        manager.onExceededDatabaseQuota("1", "1", originQuota, database1EstimatedSize,
                totalUsedQuota, mQuotaUpdater);
        assertEquals(database1EstimatedSize, mNewQuota);
        originQuota = mNewQuota;
        totalUsedQuota = originQuota;

        // Now try to create a new database under the origin, by invoking onExceededDatabaseQuota
        // again. This time, request more space than the old quota + the quota increase step.
        long database2EstimatedSize = bytes(3.5);
        manager.onExceededDatabaseQuota("1", "2", originQuota, database2EstimatedSize,
                totalUsedQuota, mQuotaUpdater);
        assertEquals(database1EstimatedSize + database2EstimatedSize, mNewQuota);
        originQuota = mNewQuota;
        totalUsedQuota = originQuota;

        // Create another database, but this time use a size that will overflow the space on the
        // device. It should be denied.
        long database3EstimatedSize = bytes(50);
        manager.onExceededDatabaseQuota("1", "3", originQuota, database3EstimatedSize,
                totalUsedQuota, mQuotaUpdater);
        assertEquals(originQuota, mNewQuota);

        // Create another database. This time, request less than the old quota.
        long database4EstimatedSize = bytes(2);
        manager.onExceededDatabaseQuota("1", "4", originQuota, database4EstimatedSize,
                totalUsedQuota, mQuotaUpdater);
        assertEquals(database1EstimatedSize + database2EstimatedSize + database4EstimatedSize,
                mNewQuota);
        originQuota = mNewQuota;
        totalUsedQuota = originQuota;

        // Now have the first database overflow it's quota. We should get 1 more MB.
        manager.onExceededDatabaseQuota("1", "1", originQuota, 0, totalUsedQuota, mQuotaUpdater);
        assertEquals(database1EstimatedSize + database2EstimatedSize + database4EstimatedSize +
                bytes(1), mNewQuota);
        originQuota = mNewQuota;
        totalUsedQuota = originQuota;

        // Create a db under the origin that uses a quota less than the usual quota increase step.
        long database5EstimatedSize = bytes(0.5);
        manager.onExceededDatabaseQuota("1", "5", originQuota, database5EstimatedSize,
                totalUsedQuota, mQuotaUpdater);
        assertEquals(database1EstimatedSize + database2EstimatedSize + database4EstimatedSize +
                bytes(1) + database5EstimatedSize, mNewQuota);
    }
}
