package net.pokeranalytics.android.filter

import androidx.test.ext.junit.runners.AndroidJUnit4
import net.pokeranalytics.android.model.filter.DateFilterable
import net.pokeranalytics.android.model.filter.FilterManager
import net.pokeranalytics.android.model.realm.Session
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import java.util.*

@RunWith(AndroidJUnit4::class)
class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() {

    @Test
    fun testDayOfWeekFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()

        val cal = Calendar.getInstance() // creates calendar
        cal.time = Date() // sets calendar time/date
        val s1 = Session.testInstance(100.0, false, cal.time)
        cal.add(Calendar.DAY_OF_MONTH, 1) // adds one hour
        Session.testInstance(100.0, true, cal.time)
        realm.commitTransaction()

        val filter = DateFilterable.DAY_OF_WEEK
        cal.time = s1.startDate
        filter.valueMap = mapOf("dayOfWeek" to cal.get(Calendar.DAY_OF_WEEK))

        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(filter)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s1.id, (this as Session).id)
        }
    }

    @Test
    fun testMonthFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()
        val cal = Calendar.getInstance()
        cal.time = Date()
        val s1 = Session.testInstance(100.0, false, cal.time)
        cal.add(Calendar.MONTH, 1)
        
        Session.testInstance(100.0, true, cal.time)
        realm.commitTransaction()

        val filter = DateFilterable.MONTH
        cal.time = s1.startDate
        filter.valueMap = mapOf("month" to cal.get(Calendar.MONTH))

        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(filter)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s1.id, (this as Session).id)
        }
    }

    @Test
    fun testYearFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()
        val cal = Calendar.getInstance()
        cal.time = Date()
        val s1 = Session.testInstance(100.0, false, cal.time)
        cal.add(Calendar.YEAR, 1)
        
        Session.testInstance(100.0, true, cal.time)
        realm.commitTransaction()

        val filter = DateFilterable.YEAR
        cal.time = s1.startDate
        filter.valueMap = mapOf("year" to cal.get(Calendar.YEAR))

        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(filter)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s1.id, (this as Session).id)
        }
    }


    @Test
    fun testWeekEndFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()
        val cal = Calendar.getInstance()
        cal.time = Date()
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY)
        val s1 = Session.testInstance(100.0, false, cal.time)
        cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY)
        
        Session.testInstance(100.0, true, cal.time)
        realm.commitTransaction()
        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(DateFilterable.WEEK_END)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s1.id, (this as Session).id)
        }
    }

    @Test
    fun testWeekDayFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()
        val cal = Calendar.getInstance()
        cal.time = Date()
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
        val s1 = Session.testInstance(100.0, false, cal.time)
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
        
        Session.testInstance(100.0, true, cal.time)
        realm.commitTransaction()
        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(DateFilterable.WEEK_DAY)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s1.id, (this as Session).id)
        }
    }

    @Test
    fun testStartedFomDateFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()

        val cal = Calendar.getInstance() // creates calendar
        cal.time = Date() // sets calendar time/date
        
        Session.testInstance(100.0, false, cal.time, 1)

        cal.add(Calendar.HOUR_OF_DAY, 2) // adds one hour
        val s2 = Session.testInstance(100.0, true, cal.time, 1)
        realm.commitTransaction()

        val filter = DateFilterable.STARTED_FROM_DATE
        filter.valueMap = mapOf("date" to s2.startDate)

        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(filter)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s2.id, (this as Session).id)
        }
    }

    @Test
    fun testStartedToDateFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()

        val cal = Calendar.getInstance() // creates calendar
        cal.time = Date() // sets calendar time/date
        val s1 = Session.testInstance(100.0, false, cal.time, 1)

        cal.add(Calendar.HOUR_OF_DAY, 2) // adds one hour
        Session.testInstance(100.0, true, cal.time, 1)

        realm.commitTransaction()

        val filter = DateFilterable.STARTED_TO_DATE
        filter.valueMap = mapOf("date" to s1.startDate)

        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(filter)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s1.id, (this as Session).id)
        }
    }

    @Test
    fun testEndedFomDateFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()

        val cal = Calendar.getInstance() // creates calendar
        cal.time = Date() // sets calendar time/date
        
        Session.testInstance(100.0, false, cal.time, 1)

        cal.add(Calendar.HOUR_OF_DAY, 2) // adds one hour
        val s2 = Session.testInstance(100.0, true, cal.time, 1)

        realm.commitTransaction()

        val filter = DateFilterable.ENDED_FROM_DATE
        filter.valueMap = mapOf("date" to s2.endDate)

        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(filter)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s2.id, (this as Session).id)
        }
    }

    @Test
    fun testEndedToDateFilter() {

        val realm = this.mockRealm
        realm.beginTransaction()

        val cal = Calendar.getInstance() // creates calendar
        cal.time = Date() // sets calendar time/date
        val s1 = Session.testInstance(100.0, false, cal.time, 1)

        cal.add(Calendar.HOUR_OF_DAY, 2) // adds one hour
        
        Session.testInstance(100.0, true, cal.time, 1)
        realm.commitTransaction()


        val filter = DateFilterable.ENDED_TO_DATE
        filter.valueMap = mapOf("date" to s1.endDate)

        val sessions = FilterManager().filter(
            realm,
            Session::class.java,
            arrayListOf(filter)
        )

        Assert.assertEquals(1, sessions.size)
        sessions[0]?.run {
            Assert.assertEquals(s1.id, (this as Session).id)
        }
    }
}