package net.pokeranalytics.android

import androidx.test.ext.junit.runners.AndroidJUnit4
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.Currency
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import java.util.*

@RunWith(AndroidJUnit4::class)
class BankrollInstrumentedUnitTest : RealmInstrumentedUnitTest() {

	// convenience extension
	fun Session.Companion.testInstance(netResult: Double, startDate: Date, endDate: Date?): Session {
		val session: Session = Session.newInstance(super.mockRealm, false)
		session.result?.netResult = netResult
		session.startDate = startDate
		session.endDate = endDate
		return session
	}

	@Test
	fun testSessionStats() {

		val realm = this.mockRealm
		realm.beginTransaction()

		val s1 = RealmInstrumentedUnitTest.newSessionInstance(realm)
		val s2 = RealmInstrumentedUnitTest.newSessionInstance(realm)

		val br1 = realm.createObject(Bankroll::class.java, "1")
		val br2 = realm.createObject(Bankroll::class.java, "2")

		val c1 = realm.createObject(Currency::class.java, "1")
		val c2 = realm.createObject(Currency::class.java, "2")
		c1.rate = 0.1
		c2.rate = 2.0
		br1.currency = c1
		br2.currency = c2

		s1.bankroll = br1
		s2.bankroll = br2

		s1.result?.netResult = 100.0
		s2.result?.netResult = 200.0

		realm.commitTransaction()

		val computableResults = realm.where(ComputableResult::class.java).findAll()
		val sets = realm.where(SessionSet::class.java).findAll()
		val stats: List<Stat> = listOf(Stat.NETRESULT, Stat.AVERAGE)
		val group = ComputableGroup("test", computableResults, sets, stats)

		val options = Calculator.Options()

		val results: ComputedResults = Calculator.compute(group, options)
		val delta = 0.01

		val sum = results.computedStat(Stat.NETRESULT)
		if (sum != null) {
			Assert.assertEquals(410.0, sum.value, delta)
		} else {
			Assert.fail("No Net result stat")
		}

		val average = results.computedStat(Stat.AVERAGE)
		if (average != null) {
			Assert.assertEquals(205.0, average.value, delta)
		} else {
			Assert.fail("No AVERAGE stat")
		}

	}

}