/*
 * Copyright (C) 2017 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.arch.paging

import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions

@RunWith(JUnit4::class)
class ItemKeyedDataSourceTest {

    // ----- STANDARD -----

    private fun loadInitial(dataSource: ItemDataSource, key: Key?, initialLoadSize: Int,
            enablePlaceholders: Boolean): PageResult<Item> {
        @Suppress("UNCHECKED_CAST")
        val receiver = mock(PageResult.Receiver::class.java) as PageResult.Receiver<Item>
        @Suppress("UNCHECKED_CAST")
        val captor = ArgumentCaptor.forClass(PageResult::class.java)
                as ArgumentCaptor<PageResult<Item>>

        dataSource.dispatchLoadInitial(key, initialLoadSize,
                /* ignored pageSize */ 10, enablePlaceholders, FailExecutor(), receiver)

        verify(receiver).onPageResult(anyInt(), captor.capture())
        verifyNoMoreInteractions(receiver)
        assertNotNull(captor.value)
        return captor.value
    }

    @Test
    fun loadInitial() {
        val dataSource = ItemDataSource()
        val result = loadInitial(dataSource, dataSource.getKey(ITEMS_BY_NAME_ID[49]), 10, true)

        assertEquals(45, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(45, 55), result.page)
        assertEquals(45, result.trailingNulls)
    }

    @Test
    fun loadInitial_keyMatchesSingleItem() {
        val dataSource = ItemDataSource(items = ITEMS_BY_NAME_ID.subList(0, 1))

        // this is tricky, since load after and load before with the passed key will fail
        val result = loadInitial(dataSource, dataSource.getKey(ITEMS_BY_NAME_ID[0]), 20, true)

        assertEquals(0, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(0, 1), result.page)
        assertEquals(0, result.trailingNulls)
    }

    @Test
    fun loadInitial_keyMatchesLastItem() {
        val dataSource = ItemDataSource()

        // tricky, because load after key is empty, so another load before and load after required
        val key = dataSource.getKey(ITEMS_BY_NAME_ID.last())
        val result = loadInitial(dataSource, key, 20, true)

        assertEquals(90, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(90, 100), result.page)
        assertEquals(0, result.trailingNulls)
    }

    @Test
    fun loadInitial_nullKey() {
        val dataSource = ItemDataSource()

        // dispatchLoadInitial(null, count) == dispatchLoadInitial(count)
        val result = loadInitial(dataSource, null, 10, true)

        assertEquals(0, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(0, 10), result.page)
        assertEquals(90, result.trailingNulls)
    }

    @Test
    fun loadInitial_keyPastEndOfList() {
        val dataSource = ItemDataSource()

        // if key is past entire data set, should return last items in data set
        val key = Key("fz", 0)
        val result = loadInitial(dataSource, key, 10, true)

        // NOTE: ideally we'd load 10 items here, but it adds complexity and unpredictability to
        // do: load after was empty, so pass full size to load before, since this can incur larger
        // loads than requested (see keyMatchesLastItem test)
        assertEquals(95, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(95, 100), result.page)
        assertEquals(0, result.trailingNulls)
    }

    // ----- UNCOUNTED -----

    @Test
    fun loadInitial_disablePlaceholders() {
        val dataSource = ItemDataSource()

        // dispatchLoadInitial(key, count) == null padding, loadAfter(key, count), null padding
        val key = dataSource.getKey(ITEMS_BY_NAME_ID[49])
        val result = loadInitial(dataSource, key, 10, false)

        assertEquals(0, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(45, 55), result.page)
        assertEquals(0, result.trailingNulls)
    }

    @Test
    fun loadInitial_uncounted() {
        val dataSource = ItemDataSource(counted = false)

        // dispatchLoadInitial(key, count) == null padding, loadAfter(key, count), null padding
        val key = dataSource.getKey(ITEMS_BY_NAME_ID[49])
        val result = loadInitial(dataSource, key, 10, true)

        assertEquals(0, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(45, 55), result.page)
        assertEquals(0, result.trailingNulls)
    }

    @Test
    fun loadInitial_nullKey_uncounted() {
        val dataSource = ItemDataSource(counted = false)

        // dispatchLoadInitial(null, count) == dispatchLoadInitial(count)
        val result = loadInitial(dataSource, null, 10, true)

        assertEquals(0, result.leadingNulls)
        assertEquals(ITEMS_BY_NAME_ID.subList(0, 10), result.page)
        assertEquals(0, result.trailingNulls)
    }

    // ----- EMPTY -----

    @Test
    fun loadInitial_empty() {
        val dataSource = ItemDataSource(items = ArrayList())

        // dispatchLoadInitial(key, count) == null padding, loadAfter(key, count), null padding
        val key = dataSource.getKey(ITEMS_BY_NAME_ID[49])
        val result = loadInitial(dataSource, key, 10, true)

        assertEquals(0, result.leadingNulls)
        assertTrue(result.page.isEmpty())
        assertEquals(0, result.trailingNulls)
    }

    @Test
    fun loadInitial_nullKey_empty() {
        val dataSource = ItemDataSource(items = ArrayList())
        val result = loadInitial(dataSource, null, 10, true)

        assertEquals(0, result.leadingNulls)
        assertTrue(result.page.isEmpty())
        assertEquals(0, result.trailingNulls)
    }

    // ----- Other behavior -----

    @Test
    fun loadBefore() {
        val dataSource = ItemDataSource()
        @Suppress("UNCHECKED_CAST")
        val callback = mock(ItemKeyedDataSource.LoadCallback::class.java)
                as ItemKeyedDataSource.LoadCallback<Item>

        dataSource.loadBefore(
                ItemKeyedDataSource.LoadParams(dataSource.getKey(ITEMS_BY_NAME_ID[5]), 5), callback)

        @Suppress("UNCHECKED_CAST")
        val argument = ArgumentCaptor.forClass(List::class.java) as ArgumentCaptor<List<Item>>
        verify(callback).onResult(argument.capture())
        verifyNoMoreInteractions(callback)

        val observed = argument.value

        assertEquals(ITEMS_BY_NAME_ID.subList(0, 5), observed)
    }

    internal data class Key(val name: String, val id: Int)

    internal data class Item(
            val name: String, val id: Int, val balance: Double, val address: String)

    internal class ItemDataSource(private val counted: Boolean = true,
                                  private val items: List<Item> = ITEMS_BY_NAME_ID)
            : ItemKeyedDataSource<Key, Item>() {

        override fun loadInitial(
                params: LoadInitialParams<Key>,
                callback: LoadInitialCallback<Item>) {
            val key = params.requestedInitialKey ?: Key("", Integer.MAX_VALUE)
            val start = Math.max(0, findFirstIndexAfter(key) - params.requestedLoadSize / 2)
            val endExclusive = Math.min(start + params.requestedLoadSize, items.size)

            if (params.placeholdersEnabled && counted) {
                callback.onResult(items.subList(start, endExclusive), start, items.size)
            } else {
                callback.onResult(items.subList(start, endExclusive))
            }
        }

        override fun loadAfter(params: LoadParams<Key>, callback: LoadCallback<Item>) {
            val start = findFirstIndexAfter(params.key)
            val endExclusive = Math.min(start + params.requestedLoadSize, items.size)

            callback.onResult(items.subList(start, endExclusive))
        }

        override fun loadBefore(params: LoadParams<Key>, callback: LoadCallback<Item>) {
            val firstIndexBefore = findFirstIndexBefore(params.key)
            val endExclusive = Math.max(0, firstIndexBefore + 1)
            val start = Math.max(0, firstIndexBefore - params.requestedLoadSize + 1)

            callback.onResult(items.subList(start, endExclusive))
        }

        override fun getKey(item: Item): Key {
            return Key(item.name, item.id)
        }

        private fun findFirstIndexAfter(key: Key): Int {
            return items.indices.firstOrNull {
                KEY_COMPARATOR.compare(key, getKey(items[it])) < 0
            } ?: items.size
        }

        private fun findFirstIndexBefore(key: Key): Int {
            return items.indices.reversed().firstOrNull {
                KEY_COMPARATOR.compare(key, getKey(items[it])) > 0
            } ?: -1
        }
    }

    private fun performLoadInitial(
            invalidateDataSource: Boolean = false,
            callbackInvoker: (callback: ItemKeyedDataSource.LoadInitialCallback<String>) -> Unit) {
        val dataSource = object : ItemKeyedDataSource<String, String>() {
            override fun getKey(item: String): String {
                return ""
            }

            override fun loadInitial(
                    params: LoadInitialParams<String>,
                    callback: LoadInitialCallback<String>) {
                if (invalidateDataSource) {
                    // invalidate data source so it's invalid when onResult() called
                    invalidate()
                }
                callbackInvoker(callback)
            }

            override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<String>) {
                fail("loadAfter not expected")
            }

            override fun loadBefore(params: LoadParams<String>, callback: LoadCallback<String>) {
                fail("loadBefore not expected")
            }
        }

        ContiguousPagedList<String, String>(
                dataSource, FailExecutor(), FailExecutor(), null,
                PagedList.Config.Builder()
                        .setPageSize(10)
                        .build(),
                "",
                ContiguousPagedList.LAST_LOAD_UNSPECIFIED)
    }

    @Test
    fun loadInitialCallbackSuccess() = performLoadInitial {
        // LoadInitialCallback correct usage
        it.onResult(listOf("a", "b"), 0, 2)
    }

    @Test
    fun loadInitialCallbackNotPageSizeMultiple() = performLoadInitial {
        // Keyed LoadInitialCallback *can* accept result that's not a multiple of page size
        val elevenLetterList = List(11) { "" + 'a' + it }
        it.onResult(elevenLetterList, 0, 12)
    }

    @Test(expected = IllegalArgumentException::class)
    fun loadInitialCallbackListTooBig() = performLoadInitial {
        // LoadInitialCallback can't accept pos + list > totalCount
        it.onResult(listOf("a", "b", "c"), 0, 2)
    }

    @Test(expected = IllegalArgumentException::class)
    fun loadInitialCallbackPositionTooLarge() = performLoadInitial {
        // LoadInitialCallback can't accept pos + list > totalCount
        it.onResult(listOf("a", "b"), 1, 2)
    }

    @Test(expected = IllegalArgumentException::class)
    fun loadInitialCallbackPositionNegative() = performLoadInitial {
        // LoadInitialCallback can't accept negative position
        it.onResult(listOf("a", "b", "c"), -1, 2)
    }

    @Test(expected = IllegalArgumentException::class)
    fun loadInitialCallbackEmptyCannotHavePlaceholders() = performLoadInitial {
        // LoadInitialCallback can't accept empty result unless data set is empty
        it.onResult(emptyList(), 0, 2)
    }

    @Test
    fun initialLoadCallbackInvalidThreeArg() = performLoadInitial(invalidateDataSource = true) {
        // LoadInitialCallback doesn't throw on invalid args if DataSource is invalid
        it.onResult(emptyList(), 0, 1)
    }

    private abstract class WrapperDataSource<K, A, B>(private val source: ItemKeyedDataSource<K, A>)
            : ItemKeyedDataSource<K, B>() {
        private val invalidatedCallback = DataSource.InvalidatedCallback {
            invalidate()
            removeCallback()
        }

        init {
            source.addInvalidatedCallback(invalidatedCallback)
        }

        private fun removeCallback() {
            removeInvalidatedCallback(invalidatedCallback)
        }

        override fun loadInitial(params: LoadInitialParams<K>, callback: LoadInitialCallback<B>) {
            source.loadInitial(params, object : LoadInitialCallback<A>() {
                override fun onResult(data: List<A>, position: Int, totalCount: Int) {
                    callback.onResult(convert(data), position, totalCount)
                }

                override fun onResult(data: MutableList<A>) {
                    callback.onResult(convert(data))
                }
            })
        }

        override fun loadAfter(params: LoadParams<K>, callback: LoadCallback<B>) {
            source.loadAfter(params, object : LoadCallback<A>() {
                override fun onResult(data: MutableList<A>) {
                    callback.onResult(convert(data))
                }
            })
        }

        override fun loadBefore(params: LoadParams<K>, callback: LoadCallback<B>) {
            source.loadBefore(params, object : LoadCallback<A>() {
                override fun onResult(data: MutableList<A>) {
                    callback.onResult(convert(data))
                }
            })
        }

        protected abstract fun convert(source: List<A>): List<B>
    }

    private data class DecoratedItem(val item: Item)

    private class DecoratedWrapperDataSource(private val source: ItemKeyedDataSource<Key, Item>)
            : WrapperDataSource<Key, Item, DecoratedItem>(source) {
        override fun convert(source: List<Item>): List<DecoratedItem> {
            return source.map { DecoratedItem(it) }
        }

        override fun getKey(item: DecoratedItem): Key {
            return source.getKey(item.item)
        }
    }

    @Test
    fun simpleWrappedDataSource() {
        // verify that it's possible to wrap an ItemKeyedDataSource, and add info to its data

        val orig = ItemDataSource(items = ITEMS_BY_NAME_ID)
        val wrapper = DecoratedWrapperDataSource(orig)

        // load initial
        @Suppress("UNCHECKED_CAST")
        val loadInitialCallback = mock(ItemKeyedDataSource.LoadInitialCallback::class.java)
                as ItemKeyedDataSource.LoadInitialCallback<DecoratedItem>
        val initKey = orig.getKey(ITEMS_BY_NAME_ID.first())
        wrapper.loadInitial(ItemKeyedDataSource.LoadInitialParams(initKey, 10, false),
                loadInitialCallback)
        verify(loadInitialCallback).onResult(
                ITEMS_BY_NAME_ID.subList(0, 10).map { DecoratedItem(it) })
        verifyNoMoreInteractions(loadInitialCallback)

        @Suppress("UNCHECKED_CAST")
        val loadCallback = mock(ItemKeyedDataSource.LoadCallback::class.java)
                as ItemKeyedDataSource.LoadCallback<DecoratedItem>
        val key = orig.getKey(ITEMS_BY_NAME_ID[20])
        // load after
        wrapper.loadAfter(ItemKeyedDataSource.LoadParams(key, 10), loadCallback)
        verify(loadCallback).onResult(ITEMS_BY_NAME_ID.subList(21, 31).map { DecoratedItem(it) })
        verifyNoMoreInteractions(loadCallback)

        // load before
        wrapper.loadBefore(ItemKeyedDataSource.LoadParams(key, 10), loadCallback)
        verify(loadCallback).onResult(ITEMS_BY_NAME_ID.subList(10, 20).map { DecoratedItem(it) })
        verifyNoMoreInteractions(loadCallback)
    }

    companion object {
        private val ITEM_COMPARATOR = compareBy<Item>({ it.name }).thenByDescending({ it.id })
        private val KEY_COMPARATOR = compareBy<Key>({ it.name }).thenByDescending({ it.id })

        private val ITEMS_BY_NAME_ID = List(100) {
            val names = Array(10) { "f" + ('a' + it) }
            Item(names[it % 10],
                    it,
                    Math.random() * 1000,
                    (Math.random() * 200).toInt().toString() + " fake st.")
        }.sortedWith(ITEM_COMPARATOR)
    }
}
