/*
 * Copyright (C) 2020 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.content.res.loader.cts

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.AssetManager
import android.content.res.Configuration
import android.content.res.Resources
import android.content.res.loader.ResourcesLoader
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.os.IBinder
import androidx.test.rule.ActivityTestRule
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.util.Collections

/**
 * Tests generic ResourceLoader behavior. Intentionally abstract in its test methodology because
 * the behavior being verified isn't specific to any resource type. As long as it can pass an
 * equals check.
 *
 * Currently tests strings and dimens since String and any Number seemed most relevant to verify.
 */
@RunWith(Parameterized::class)
class ResourcesLoaderValuesTest : ResourcesLoaderTestBase() {

    @get:Rule
    private val mTestActivityRule = ActivityTestRule<TestActivity>(TestActivity::class.java)

    companion object {
        @Parameterized.Parameters(name = "{1} {0}")
        @JvmStatic
        fun parameters(): Array<Any> {
            val parameters = mutableListOf<Parameter>()

            // Test resolution of resources encoded within the resources.arsc.
            parameters += Parameter(
                    "tableBased",
                    query(mapOf(
                            "getOverlaid" to { res ->
                                res.getString(R.string.test)
                            },
                            "getAdditional" to { res ->
                                res.getString(0x7f0400fe /* R.string.additional */)
                            },
                            "getIdentifier" to { res ->
                                res.getString(res.getIdentifier("test", "string",
                                        "android.content.res.loader.cts"))
                            },
                            "getIdentifierAdditional" to { res ->
                                res.getString(res.getIdentifier("additional", "string",
                                        "android.content.res.loader.cts"))
                            }
                    )),
                    mapOf("getOverlaid" to "Not overlaid",
                            "getAdditional" to "NotFoundException",
                            "getIdentifier" to "Not overlaid",
                            "getIdentifierAdditional" to "NotFoundException"),

                    mapOf("getOverlaid" to "One",
                            "getAdditional" to "One",
                            "getIdentifier" to "One",
                            "getIdentifierAdditional" to "One"),

                    mapOf("getOverlaid" to "Two",
                            "getAdditional" to "Two",
                            "getIdentifier" to "Two",
                            "getIdentifierAdditional" to "Two"),

                    mapOf("getOverlaid" to "Three",
                            "getAdditional" to "Three",
                            "getIdentifier" to "Three",
                            "getIdentifierAdditional" to "Three"),

                    mapOf("getOverlaid" to "Four",
                            "getAdditional" to "Four",
                            "getIdentifier" to "Four",
                            "getIdentifierAdditional" to "Four"),
                    listOf(DataType.APK_DISK_FD_NO_ASSETS_PROVIDER, DataType.APK_DISK_FD,
                            DataType.APK_DISK_FD_OFFSETS, DataType.APK_RAM_FD,
                            DataType.APK_RAM_OFFSETS, DataType.ARSC_DISK_FD,
                            DataType.ARSC_DISK_FD_OFFSETS, DataType.ARSC_RAM_MEMORY,
                            DataType.ARSC_RAM_MEMORY_OFFSETS, DataType.SPLIT, DataType.DIRECTORY)
            )

            // Test resolution of file-based resources and assets with no assets provider.
            parameters += Parameter(
                    "tableFileBased",
                    query(mapOf(
                            // Drawable xml in res directory
                            "drawableXml" to { res ->
                                (res.getDrawable(R.drawable.drawable_xml) as ColorDrawable)
                                        .color.toString()
                            },
                            // Asset as compiled XML layout in res directory
                            "layout" to { res ->
                                res.getLayout(R.layout.layout).advanceToRoot().name
                            },
                            // Bitmap drawable in res directory
                            "drawablePng" to { res ->
                                (res.getDrawable(R.drawable.drawable_png) as BitmapDrawable)
                                        .bitmap.getColor(0, 0).toArgb().toString()
                            }
                    )),
                    mapOf("drawableXml" to Color.parseColor("#B2D2F2").toString(),
                            "layout" to "MysteryLayout",
                            "drawablePng" to Color.parseColor("#FF00FF").toString()),

                    mapOf("drawableXml" to Color.parseColor("#000001").toString(),
                            "layout" to "RelativeLayout",
                            "drawablePng" to Color.RED.toString()),

                    mapOf("drawableXml" to Color.parseColor("#000002").toString(),
                            "layout" to "LinearLayout",
                            "drawablePng" to Color.GREEN.toString()),

                    mapOf("drawableXml" to Color.parseColor("#000003").toString(),
                            "layout" to "FrameLayout",
                            "drawablePng" to Color.BLUE.toString()),

                    mapOf("drawableXml" to Color.parseColor("#000004").toString(),
                            "layout" to "TableLayout",
                            "drawablePng" to Color.WHITE.toString()),
                    listOf(DataType.APK_DISK_FD_NO_ASSETS_PROVIDER, DataType.APK_DISK_FD,
                            DataType.APK_DISK_FD_OFFSETS, DataType.APK_RAM_FD,
                            DataType.APK_RAM_OFFSETS, DataType.SPLIT, DataType.DIRECTORY)
            )

            // Test resolution of assets.
            parameters += Parameter(
                    "fileBased",
                    query(mapOf(
                            // File in the assets directory
                            "openAsset" to { res ->
                                res.assets.open("asset.txt").reader().readText()
                            },
                            // From assets directory returning file descriptor
                            "openAssetFd" to { res ->
                                res.assets.openFd("asset.txt").readText()
                            },
                            // Asset as compiled XML layout in res directory
                            "layout" to { res ->
                                res.assets.openXmlResourceParser("res/layout/layout.xml")
                                        .advanceToRoot().name
                            }
                    )),
                    mapOf("openAsset" to "In assets directory",
                            "openAssetFd" to "In assets directory",
                            "layout" to "MysteryLayout"),

                    mapOf("openAsset" to "One",
                            "openAssetFd" to "One",
                            "layout" to "RelativeLayout"),

                    mapOf("openAsset" to "Two",
                            "openAssetFd" to "Two",
                            "layout" to "LinearLayout"),

                    mapOf("openAsset" to "Three",
                            "openAssetFd" to "Three",
                            "layout" to "FrameLayout"),

                    mapOf("openAsset" to "Four",
                            "openAssetFd" to "Four",
                            "layout" to "TableLayout"),
                    listOf(DataType.EMPTY)
            )

            // Test assets from apk and provider
            parameters += Parameter(
                    "fileBasedApkAssetsProvider",
                    query(mapOf(
                            // File in the assets directory
                            "openAsset" to { res ->
                                res.assets.open("asset.txt").reader().readText()
                            },
                            // From assets directory returning file descriptor
                            "openAssetFd" to { res ->
                                res.assets.openFd("asset.txt").readText()
                            }
                    )),
                    mapOf("openAsset" to "In assets directory",
                            "openAssetFd" to "In assets directory"),

                    mapOf("openAsset" to "AssetsOne",
                            "openAssetFd" to "AssetsOne"),
                    { MemoryAssetsProvider().addLoadAssetFdResult("assets/asset.txt",
                            "AssetsOne") },

                    mapOf("openAsset" to "Two",
                            "openAssetFd" to "Two"),
                    null /* assetProviderTwo */,

                    mapOf("openAsset" to "AssetsThree",
                            "openAssetFd" to "AssetsThree"),
                    { MemoryAssetsProvider().addLoadAssetFdResult("assets/asset.txt",
                            "AssetsThree") },

                    mapOf("openAsset" to "Four",
                            "openAssetFd" to "Four"),
                    null /* assetProviderFour */,
                    listOf(DataType.APK_DISK_FD, DataType.APK_DISK_FD_OFFSETS, DataType.APK_RAM_FD,
                            DataType.APK_RAM_OFFSETS, DataType.DIRECTORY)

            )

            return parameters.flatMap { parameter ->
                parameter.dataTypes.map { dataType ->
                    arrayOf(dataType, parameter)
                }
            }.toTypedArray()
        }
    }

    @Suppress("LateinitVarOverridesLateinitVar")
    @field:Parameterized.Parameter(0)
    override lateinit var dataType: DataType

    @field:Parameterized.Parameter(1)
    lateinit var parameter: Parameter

    private val valueOriginal by lazy { mapToString(parameter.valueOriginal) }
    private val valueOne by lazy { mapToString(parameter.valueOne) }
    private val valueTwo by lazy { mapToString(parameter.valueTwo) }
    private val valueThree by lazy { mapToString(parameter.valueThree) }
    private val valueFour by lazy { mapToString(parameter.valueFour) }

    private fun openOne() = PROVIDER_ONE.openProvider(dataType,
            parameter.assetProviderOne?.invoke())
    private fun openTwo() = PROVIDER_TWO.openProvider(dataType,
            parameter.assetProviderTwo?.invoke())
    private fun openThree() = PROVIDER_THREE.openProvider(dataType,
            parameter.assetProviderThree?.invoke())
    private fun openFour() = PROVIDER_FOUR.openProvider(dataType,
            parameter.assetProviderFour?.invoke())
    private fun openEmpty() = PROVIDER_EMPTY.openProvider(DataType.EMPTY, null)

    // Class method for syntax highlighting purposes
    private fun getValue(c: Context = context) = parameter.getValue(c.resources)
    private fun getValue(r: Resources) = parameter.getValue(r)

    @Test
    fun assertValueUniqueness() {
        // Ensure the parameters are valid in case of coding errors
        val original = getValue()
        assertEquals(valueOriginal, original)
        assertNotEquals(valueOne, original)
        assertNotEquals(valueTwo, original)
        assertNotEquals(valueThree, original)
        assertNotEquals(valueFour, original)
        assertNotEquals(valueTwo, valueOne)
        assertNotEquals(valueThree, valueOne)
        assertNotEquals(valueFour, valueOne)
        assertNotEquals(valueThree, valueTwo)
        assertNotEquals(valueFour, valueTwo)
        assertNotEquals(valueFour, valueThree)
    }

    @Test
    fun addProvidersRepeatedly() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.addProvider(testOne)
        assertEquals(valueOne, getValue())

        loader.addProvider(testTwo)
        assertEquals(valueTwo, getValue())

        loader.removeProvider(testOne)
        assertEquals(valueTwo, getValue())

        loader.removeProvider(testTwo)
        assertEquals(valueOriginal, getValue())
    }

    @Test
    fun addLoadersRepeatedly() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader1 = ResourcesLoader()
        val loader2 = ResourcesLoader()

        resources.addLoaders(loader1)
        loader1.addProvider(testOne)
        assertEquals(valueOne, getValue())

        resources.addLoaders(loader2)
        loader2.addProvider(testTwo)
        assertEquals(valueTwo, getValue())

        resources.removeLoaders(loader1)
        assertEquals(valueTwo, getValue())

        resources.removeLoaders(loader2)
        assertEquals(valueOriginal, getValue())
    }

    @Test
    fun setMultipleProviders() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.providers = listOf(testOne, testTwo)
        assertEquals(valueTwo, getValue())

        loader.removeProvider(testTwo)
        assertEquals(valueOne, getValue())

        loader.providers = Collections.emptyList()
        assertEquals(valueOriginal, getValue())
    }

    @Test
    fun addMultipleLoaders() {
        val loader1 = ResourcesLoader()
        loader1.addProvider(openOne())
        val loader2 = ResourcesLoader()
        loader2.addProvider(openTwo())

        resources.addLoaders(loader1, loader2)
        assertEquals(valueTwo, getValue())

        resources.removeLoaders(loader2)
        assertEquals(valueOne, getValue())

        resources.removeLoaders(loader1)
        assertEquals(valueOriginal, getValue())
    }

    @Test
    fun emptyProvider() {
        val testOne = openOne()
        val testTwo = openTwo()
        val testEmpty = openEmpty()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.providers = listOf(testOne, testEmpty, testTwo)
        assertEquals(valueTwo, getValue())

        loader.removeProvider(testTwo)
        assertEquals(valueOne, getValue())

        loader.removeProvider(testOne)
        assertEquals(valueOriginal, getValue())

        loader.providers = Collections.emptyList()
        assertEquals(valueOriginal, getValue())
    }

    @Test(expected = UnsupportedOperationException::class)
    fun getProvidersDoesNotLeakMutability() {
        val testOne = openOne()
        val loader = ResourcesLoader()
        val providers = loader.providers
        providers += testOne
    }

    @Test(expected = UnsupportedOperationException::class)
    fun getLoadersDoesNotLeakMutability() {
        val loaders = resources.loaders
        loaders += ResourcesLoader()
    }

    @Test
    fun alreadyAddedProviderNoOps() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.addProvider(testOne)
        loader.addProvider(testTwo)
        loader.addProvider(testOne)

        assertEquals(2, loader.providers.size)
        assertEquals(loader.providers[0], testOne)
        assertEquals(loader.providers[1], testTwo)
    }

    @Test
    fun alreadyAddedLoaderNoOps() {
        val loader1 = ResourcesLoader()
        loader1.addProvider(openOne())
        val loader2 = ResourcesLoader()
        loader2.addProvider(openTwo())

        resources.addLoaders(loader1)
        resources.addLoaders(loader2)
        resources.addLoaders(loader1)

        assertEquals(2, resources.loaders.size)
        assertEquals(resources.loaders[0], loader1)
        assertEquals(resources.loaders[1], loader2)
    }

    @Test
    fun repeatedRemoveProviderNoOps() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.addProvider(testOne)
        loader.addProvider(testTwo)

        loader.removeProvider(testOne)
        loader.removeProvider(testOne)

        assertEquals(1, loader.providers.size)
        assertEquals(loader.providers[0], testTwo)
    }

    @Test
    fun repeatedRemoveLoaderNoOps() {
        val loader1 = ResourcesLoader()
        loader1.addProvider(openOne())
        val loader2 = ResourcesLoader()
        loader2.addProvider(openTwo())

        resources.addLoaders(loader1, loader2)
        resources.removeLoaders(loader1)
        resources.removeLoaders(loader1)

        assertEquals(1, resources.loaders.size)
        assertEquals(resources.loaders[0], loader2)

        resources.removeLoaders(loader2, loader2)

        assertEquals(0, resources.loaders.size)
    }

    @Test
    fun repeatedSetProvider() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.providers = listOf(testOne, testTwo)
        loader.providers = listOf(testOne, testTwo)

        assertEquals(2, loader.providers.size)
        assertEquals(loader.providers[0], testOne)
        assertEquals(loader.providers[1], testTwo)
    }

    @Test
    fun clearProviders() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.providers = listOf(testOne, testTwo)
        assertEquals(2, loader.providers.size)
        assertEquals(valueTwo, getValue())

        loader.clearProviders()
        assertEquals(0, loader.providers.size)
        assertEquals(valueOriginal, getValue())
    }

    @Test
    fun repeatedAddMultipleLoaders() {
        val loader1 = ResourcesLoader()
        loader1.addProvider(openOne())
        val loader2 = ResourcesLoader()
        loader2.addProvider(openTwo())

        resources.addLoaders(loader1, loader2)
        resources.addLoaders(loader1, loader2)

        assertEquals(2, resources.loaders.size)
        assertEquals(resources.loaders[0], loader1)
        assertEquals(resources.loaders[1], loader2)
    }

    @Test
    fun reorderProviders() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.addProvider(testOne)
        loader.addProvider(testTwo)
        assertEquals(valueTwo, getValue())

        loader.removeProvider(testOne)
        assertEquals(valueTwo, getValue())

        loader.addProvider(testOne)
        assertEquals(valueOne, getValue())

        loader.removeProvider(testTwo)
        assertEquals(valueOne, getValue())

        loader.removeProvider(testOne)
        assertEquals(valueOriginal, getValue())
    }

    @Test
    fun reorderLoaders() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader1 = ResourcesLoader()
        loader1.addProvider(testOne)
        val loader2 = ResourcesLoader()
        loader2.addProvider(testTwo)

        resources.addLoaders(loader1)
        resources.addLoaders(loader2)
        assertEquals(valueTwo, getValue())

        resources.removeLoaders(loader1)
        assertEquals(valueTwo, getValue())

        resources.addLoaders(loader1)
        assertEquals(valueOne, getValue())

        resources.removeLoaders(loader2)
        assertEquals(valueOne, getValue())

        resources.removeLoaders(loader1)
        assertEquals(valueOriginal, getValue())
    }

    @Test
    fun reorderMultipleLoadersAndProviders() {
        val testOne = openOne()
        val testTwo = openTwo()
        val testThree = openThree()
        val testFour = openFour()

        val loader1 = ResourcesLoader()
        loader1.providers = listOf(testOne, testTwo)

        val loader2 = ResourcesLoader()
        loader2.providers = listOf(testThree, testFour)

        resources.addLoaders(loader1, loader2)
        assertEquals(valueFour, getValue())

        resources.removeLoaders(loader1)
        resources.addLoaders(loader1)
        assertEquals(valueTwo, getValue())

        loader1.removeProvider(testTwo)
        assertEquals(valueOne, getValue())

        loader1.removeProvider(testOne)
        assertEquals(valueFour, getValue())

        loader2.removeProvider(testFour)
        assertEquals(valueThree, getValue())
    }

    private fun createContext(context: Context, id: Int): Context {
        val overrideConfig = Configuration()
        overrideConfig.orientation = Int.MAX_VALUE - id
        return context.createConfigurationContext(overrideConfig)
    }

    @Test
    fun copyContextLoaders() {
        val loader1 = ResourcesLoader()
        loader1.addProvider(openOne())
        val loader2 = ResourcesLoader()
        loader2.addProvider(openTwo())

        resources.addLoaders(loader1)
        assertEquals(valueOne, getValue())

        // The child context should include the loaders of the original context.
        val childContext = createContext(context, 0)
        assertEquals(valueOne, getValue(childContext))

        // Changing the loaders of the child context should not affect the original context.
        childContext.resources.addLoaders(loader2)
        assertEquals(valueOne, getValue())
        assertEquals(valueTwo, getValue(childContext))

        // Changing the loaders of the original context should not affect the child context.
        resources.removeLoaders(loader1)
        assertEquals(valueOriginal, getValue())
        assertEquals(valueTwo, getValue(childContext))

        // A new context created from the original after an update to the original's loaders should
        // have the updated loaders.
        val originalPrime = createContext(context, 2)
        assertEquals(valueOriginal, getValue(originalPrime))

        // A new context created from the child context after an update to the child's loaders
        // should have the updated loaders.
        val childPrime = createContext(childContext, 1)
        assertEquals(valueTwo, getValue(childPrime))
    }

    @Test
    fun loaderUpdatesAffectContexts() {
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        resources.addLoaders(loader)
        loader.addProvider(testOne)
        assertEquals(valueOne, getValue())

        val childContext = createContext(context, 0)
        assertEquals(valueOne, getValue(childContext))

        // Adding a provider to a loader affects all contexts that use the loader.
        loader.addProvider(testTwo)
        assertEquals(valueTwo, getValue())
        assertEquals(valueTwo, getValue(childContext))

        // Changes to the loaders for a context do not affect providers.
        resources.clearLoaders()
        assertEquals(valueOriginal, getValue())
        assertEquals(valueTwo, getValue(childContext))

        val childContext2 = createContext(context, 1)
        assertEquals(valueOriginal, getValue())
        assertEquals(valueOriginal, getValue(childContext2))

        childContext2.resources.addLoaders(loader)
        assertEquals(valueOriginal, getValue())
        assertEquals(valueTwo, getValue(childContext))
        assertEquals(valueTwo, getValue(childContext2))
    }

    @Test
    fun appLoadersIncludedInActivityContexts() {
        val loader = ResourcesLoader()
        loader.addProvider(openOne())

        val applicationContext = context.applicationContext
        applicationContext.resources.addLoaders(loader)
        assertEquals(valueOne, getValue(applicationContext))

        val activity = mTestActivityRule.launchActivity(Intent())
        assertEquals(valueOne, getValue(activity))

        applicationContext.resources.clearLoaders()
    }

    @Test
    fun loadersApplicationInfoChanged() {
        val loader1 = ResourcesLoader()
        loader1.addProvider(openOne())
        val loader2 = ResourcesLoader()
        loader2.addProvider(openTwo())

        val applicationContext = context.applicationContext
        applicationContext.resources.addLoaders(loader1)
        assertEquals(valueOne, getValue(applicationContext))

        var token: IBinder? = null
        val activity = mTestActivityRule.launchActivity(Intent())
        mTestActivityRule.runOnUiThread(Runnable {
            token = activity.activityToken
            val at = activity.activityThread

            // The activity should have the loaders from the application.
            assertEquals(valueOne, getValue(applicationContext))
            assertEquals(valueOne, getValue(activity))

            activity.resources.addLoaders(loader2)
            assertEquals(valueOne, getValue(applicationContext))
            assertEquals(valueTwo, getValue(activity))

            // Relaunches the activity.
            at.handleApplicationInfoChanged(activity.applicationInfo)
            at.handleRelaunchActivityLocally(token)
        })

        mTestActivityRule.runOnUiThread(Runnable {
            val activityThread = activity.activityThread
            val newActivity = activityThread.getActivity(token)

            // The loader added to the activity loaders should not be persisted.
            assertEquals(valueOne, getValue(applicationContext))
            assertEquals(valueOne, getValue(newActivity))
        })

        applicationContext.resources.clearLoaders()
    }

    @Test
    fun multipleLoadersHaveSameProviders() {
        val provider1 = openOne()
        val loader1 = ResourcesLoader()
        loader1.addProvider(provider1)
        val loader2 = ResourcesLoader()
        loader2.addProvider(provider1)
        loader2.addProvider(openTwo())

        resources.addLoaders(loader1, loader2)
        assertEquals(valueTwo, getValue())

        resources.removeLoaders(loader1)
        resources.addLoaders(loader1)
        assertEquals(valueOne, getValue())

        assertEquals(2, resources.assets.apkAssets.count { apkAssets -> apkAssets.isForLoader })
    }

    @Test(expected = IllegalStateException::class)
    fun cannotUseClosedProvider() {
        val provider = openOne()
        provider.close()
        val loader = ResourcesLoader()
        loader.addProvider(provider)
    }

    @Test(expected = IllegalStateException::class)
    fun cannotCloseUsedProvider() {
        val provider = openOne()
        val loader = ResourcesLoader()
        loader.addProvider(provider)
        provider.close()
    }

    @Test
    fun addLoadersRepeatedlyCustomResources() {
        val res = Resources(AssetManager::class.java.newInstance(), resources.displayMetrics,
                resources.configuration!!)
        val originalValue = getValue(res)
        val testOne = openOne()
        val testTwo = openTwo()
        val loader1 = ResourcesLoader()
        val loader2 = ResourcesLoader()

        res.addLoaders(loader1)
        loader1.addProvider(testOne)
        assertEquals(valueOne, getValue(res))

        res.addLoaders(loader2)
        loader2.addProvider(testTwo)
        assertEquals(valueTwo, getValue(res))

        res.removeLoaders(loader1)
        res.addLoaders(loader1)
        assertEquals(valueOne, getValue(res))

        res.removeLoaders(loader1)
        assertEquals(valueTwo, getValue(res))

        res.removeLoaders(loader2)
        assertEquals(originalValue, getValue(res))
    }

    @Test
    fun setMultipleProvidersCustomResources() {
        val res = Resources(AssetManager::class.java.newInstance(), resources.displayMetrics,
                resources.configuration!!)
        val originalValue = getValue(res)
        val testOne = openOne()
        val testTwo = openTwo()
        val loader = ResourcesLoader()

        res.addLoaders(loader)
        loader.providers = listOf(testOne, testTwo)
        assertEquals(valueTwo, getValue(res))

        loader.removeProvider(testTwo)
        assertEquals(valueOne, getValue(res))

        loader.providers = Collections.emptyList()
        assertEquals(originalValue, getValue(res))
    }

    data class Parameter(
        val testPrefix: String,
        val getValue: Resources.() -> String,
        val valueOriginal: Map<String, String>,
        val valueOne: Map<String, String>,
        val assetProviderOne: (() -> MemoryAssetsProvider)? = null,
        val valueTwo: Map<String, String>,
        val assetProviderTwo: (() -> MemoryAssetsProvider)? = null,
        val valueThree: Map<String, String>,
        val assetProviderThree: (() -> MemoryAssetsProvider)? = null,
        val valueFour: Map<String, String>,
        val assetProviderFour: (() -> MemoryAssetsProvider)? = null,
        val dataTypes: List<DataType>
    ) {
        constructor(
            testPrefix: String,
            getValue: Resources.() -> String,
            valueOriginal: Map<String, String>,
            valueOne: Map<String, String>,
            valueTwo: Map<String, String>,
            valueThree: Map<String, String>,
            valueFour: Map<String, String>,
            dataTypes: List<DataType>
        ): this(testPrefix, getValue, valueOriginal, valueOne,
                null, valueTwo, null, valueThree, null, valueFour, null, dataTypes)

        override fun toString() = testPrefix
    }
}

class TestActivity : Activity()