/*
 * Copyright (C) 2014 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 android.appsecurity.cts;

import com.android.ddmlib.testrunner.TestResult.TestStatus;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.result.TestResult;
import com.android.tradefed.result.TestRunResult;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;

import junit.framework.AssertionFailedError;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assume.assumeTrue;

import java.util.Map;

/**
 * Tests that exercise various storage APIs.
 */
@RunWith(DeviceJUnit4ClassRunner.class)
public class StorageHostTest extends BaseHostJUnit4Test {
    private static final String PKG_STATS = "com.android.cts.storagestatsapp";
    private static final String PKG_A = "com.android.cts.storageapp_a";
    private static final String PKG_B = "com.android.cts.storageapp_b";
    private static final String APK_STATS = "CtsStorageStatsApp.apk";
    private static final String APK_A = "CtsStorageAppA.apk";
    private static final String APK_B = "CtsStorageAppB.apk";
    private static final String CLASS_STATS = "com.android.cts.storagestatsapp.StorageStatsTest";
    private static final String CLASS = "com.android.cts.storageapp.StorageTest";

    private int[] mUsers;

    @Before
    public void setUp() throws Exception {
        mUsers = Utils.prepareMultipleUsers(getDevice());

        installPackage(APK_STATS);
        installPackage(APK_A);
        installPackage(APK_B);

        for (int user : mUsers) {
            getDevice().executeShellCommand("appops set --user " + user + " " + PKG_STATS
                    + " android:get_usage_stats allow");
        }

        waitForIdle();
    }

    @After
    public void tearDown() throws Exception {
        getDevice().uninstallPackage(PKG_STATS);
        getDevice().uninstallPackage(PKG_A);
        getDevice().uninstallPackage(PKG_B);
    }

    @Test
    public void testVerify() throws Exception {
        Utils.runDeviceTests(getDevice(), PKG_STATS, CLASS_STATS, "testVerify");
    }

    @Test
    public void testVerifyAppStats() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_A, CLASS, "testAllocate", user);
        }

        // for fuse file system
        Thread.sleep(10000);

        // TODO: remove this once 34723223 is fixed
        getDevice().executeShellCommand("sync");

        for (int user : mUsers) {
            runDeviceTests(PKG_A, CLASS, "testVerifySpaceManual", user);
            runDeviceTests(PKG_A, CLASS, "testVerifySpaceApi", user);
        }
    }

    @Test
    public void testVerifyAppQuota() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_A, CLASS, "testVerifyQuotaApi", user);
        }
    }

    @Test
    public void testVerifyAppAllocate() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_A, CLASS, "testVerifyAllocateApi", user);
        }
    }

    @Test
    public void testVerifySummary() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifySummary", user);
        }
    }

    @Test
    public void testVerifyStats() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStats", user);
        }
    }

    @Test
    public void testVerifyStatsMultiple() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_A, CLASS, "testAllocate", user);
            runDeviceTests(PKG_A, CLASS, "testAllocate", user);

            runDeviceTests(PKG_B, CLASS, "testAllocate", user);
        }

        for (int user : mUsers) {
            runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStatsMultiple", user);
        }
    }

    @Test
    public void testVerifyStatsExternal() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStatsExternal", user, true);
        }
    }

    @Test
    public void testVerifyStatsExternalConsistent() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStatsExternalConsistent", user, true);
        }
    }

    @Test
    public void testVerifyCategory() throws Exception {
        for (int user : mUsers) {
            runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyCategory", user);
        }
    }

    @Test
    public void testCache() throws Exception {
        // To make the cache clearing logic easier to verify, ignore any cache
        // and low space reserved space.
        getDevice().executeShellCommand("settings put global sys_storage_threshold_max_bytes 0");
        getDevice().executeShellCommand("settings put global sys_storage_cache_max_bytes 0");
        getDevice().executeShellCommand("svc data disable");
        getDevice().executeShellCommand("svc wifi disable");
        try {
            waitForIdle();
            for (int user : mUsers) {
                // Clear all other cached data to give ourselves a clean slate
                getDevice().executeShellCommand("pm trim-caches 4096G");
                runDeviceTests(PKG_STATS, CLASS_STATS, "testCacheClearing", user);

                getDevice().executeShellCommand("pm trim-caches 4096G");
                runDeviceTests(PKG_STATS, CLASS_STATS, "testCacheBehavior", user);
            }
        } finally {
            getDevice().executeShellCommand("settings delete global sys_storage_threshold_max_bytes");
            getDevice().executeShellCommand("settings delete global sys_storage_cache_max_bytes");
            getDevice().executeShellCommand("svc data enable");
            getDevice().executeShellCommand("svc wifi enable");
        }
    }

    @Test
    public void testFullDisk() throws Exception {
        assumeTrue(!isWatch());
        // Clear all other cached and external storage data to give ourselves a
        // clean slate to test against
        getDevice().executeShellCommand("pm trim-caches 4096G");
        getDevice().executeShellCommand("rm -rf /sdcard/*");

        getDevice().executeShellCommand("settings put global hide_error_dialogs 1");
        try {
            try {
                // Try our hardest to fill up the entire disk
                Utils.runDeviceTestsAsCurrentUser(getDevice(), PKG_B, CLASS, "testFullDisk");
            } catch (Throwable t) {
                if (t.getMessage().contains("Skipping")) {
                    // If the device doesn't have resgid support, there's nothing
                    // for this test to verify
                    return;
                } else {
                    throw new AssertionFailedError(t.getMessage());
                }
            }

            // Tweak something that causes PackageManager to persist data
            Utils.runDeviceTestsAsCurrentUser(getDevice(), PKG_A, CLASS, "testTweakComponent");

            // Wake up/unlock device before running tests
            getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
            getDevice().disableKeyguard();

            // Verify that Settings can free space used by abusive app
            Utils.runDeviceTestsAsCurrentUser(getDevice(), PKG_A, CLASS, "testClearSpace");
        } finally {
            getDevice().executeShellCommand("settings delete global hide_error_dialogs");
        }
    }

    public void waitForIdle() throws Exception {
        // Try getting all pending events flushed out
        for (int i = 0; i < 4; i++) {
            getDevice().executeShellCommand("am wait-for-broadcast-idle");
            Thread.sleep(500);
        }
    }

    public void runDeviceTests(String packageName, String testClassName, String testMethodName,
            int userId) throws DeviceNotAvailableException {
        runDeviceTests(packageName, testClassName, testMethodName, userId, false);
    }

    public void runDeviceTests(String packageName, String testClassName, String testMethodName,
            int userId, boolean disableIsolatedStorage) throws DeviceNotAvailableException {
        final DeviceTestRunOptions options = new DeviceTestRunOptions(packageName);
        options.setDevice(getDevice());
        options.setTestClassName(testClassName);
        options.setTestMethodName(testMethodName);
        options.setUserId(userId);
        options.setTestTimeoutMs(20 * 60 * 1000L);
        options.setDisableIsolatedStorage(disableIsolatedStorage);
        if (!runDeviceTests(options)) {
            TestRunResult res = getLastDeviceRunResults();
            if (res != null) {
                StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
                for (Map.Entry<TestDescription, TestResult> resultEntry :
                    res.getTestResults().entrySet()) {
                    if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
                        errorBuilder.append(resultEntry.getKey().toString());
                        errorBuilder.append(":\n");
                        errorBuilder.append(resultEntry.getValue().getStackTrace());
                    }
                }
                throw new AssertionError(errorBuilder.toString());
            } else {
                throw new AssertionFailedError("Error when running device tests.");
            }
        }
    }

    private boolean isWatch() {
        try {
            return getDevice().hasFeature("feature:android.hardware.type.watch");
        } catch (DeviceNotAvailableException e) {
            return false;
        }
    }
}
