package net.pokeranalytics.android.unitTests

import androidx.test.ext.junit.runners.AndroidJUnit4
import io.realm.RealmResults
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.components.SessionInstrumentedUnitTest
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.Currency
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import java.text.SimpleDateFormat
import java.util.*

/**
 * Instrumented test, which will execute on an Android device.
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
@RunWith(AndroidJUnit4::class)
class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {

	@Test
	fun testAllSessionStats() {

		val realm = this.mockRealm

		val computableResults = realm.where(ComputableResult::class.java).findAll()

		assertEquals(0, computableResults.size)

		realm.beginTransaction()

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

		s1.result?.buyin = 100.0 // net result = -100
		s2.result?.buyin = 200.0
		s2.result?.cashout = 500.0 // net result = 300

		s1.cgBigBlind = 0.5 // bb net result = -200bb
		s2.cgBigBlind = 2.0 // bb net result = 150bb

		s2.tableSize = 5

		val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

		val sd1 = sdf.parse("01/1/2019 10:00")
		val ed1 = sdf.parse("01/1/2019 11:00") // 1 hour
		val sd2 = sdf.parse("02/1/2019 08:00")
		val ed2 = sdf.parse("02/1/2019 11:00") // 3 hours

		s1.startDate = sd1
		s1.endDate = ed1
		s2.startDate = sd2
		s2.endDate = ed2

		val l1 = realm.createObject(Location::class.java, UUID.randomUUID().toString())
		s1.location = l1
		s2.location = l1

		realm.commitTransaction()

		assertEquals(2, computableResults.size)

		computableResults.forEach {
			println(">>>>>> rated net = ${it.ratedNet} ")
		}

		val group = ComputableGroup(Query())

		val options = Calculator.Options()
		options.stats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION,
			Stat.LONGEST_STREAKS, Stat.LOCATIONS_PLAYED, Stat.DAYS_PLAYED)

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

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

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

		val duration = results.computedStat(Stat.HOURLY_DURATION)
		if (duration != null) {
			assertEquals(4.0, duration.value, delta)
		} else {
			Assert.fail("No netDuration stat")
		}

		val hourlyRate = results.computedStat(Stat.HOURLY_RATE)
		if (hourlyRate != null) {
			assertEquals(50.0, hourlyRate.value, delta)
		} else {
			Assert.fail("No houry rate stat")
		}
		val handsPlayed = results.computedStat(Stat.HANDS_PLAYED)
		if (handsPlayed != null) {
			assertEquals(177.77, handsPlayed.value, delta)
		} else {
			Assert.fail("No hands played stat")
		}
		val numberOfGames = results.computedStat(Stat.NUMBER_OF_GAMES)
		if (numberOfGames != null) {
			assertEquals(2, numberOfGames.value.toInt())
		} else {
			Assert.fail("No numberOfGames stat")
		}
		val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
		if (numberOfSets != null) {
			assertEquals(2, numberOfSets.value.toInt())
		} else {
			Assert.fail("No numberOfSets stat")
		}
		val avgBuyin = results.computedStat(Stat.AVERAGE_BUYIN)
		if (avgBuyin != null) {
			assertEquals(150.0, avgBuyin.value, delta)
		} else {
			Assert.fail("No avgBuyin stat")
		}
		val avgDuration = results.computedStat(Stat.AVERAGE_HOURLY_DURATION)
		if (avgDuration != null) {
			assertEquals(2.0, avgDuration.value, delta)
		} else {
			Assert.fail("No avgDuration stat")
		}
		val roi = results.computedStat(Stat.ROI)
		if (roi != null) {
			assertEquals(200 / 300.0, roi.value, delta)
		} else {
			Assert.fail("No roi stat")
		}

		val avgBBNet = results.computedStat(Stat.AVERAGE_NET_BB)
		if (avgBBNet != null) {
			assertEquals(-25.0, avgBBNet.value, delta)
		} else {
			Assert.fail("No avgBBNet stat")
		}
		val bbHourlyRate = results.computedStat(Stat.HOURLY_RATE_BB)
		if (bbHourlyRate != null) {
			assertEquals(-12.5, bbHourlyRate.value, delta)
		} else {
			Assert.fail("No bbHourlyRate stat")
		}
		val netbbPer100Hands = results.computedStat(Stat.NET_BB_PER_100_HANDS)
		if (netbbPer100Hands != null) {
			assertEquals(-28.12, netbbPer100Hands.value, delta)
		} else {
			Assert.fail("No netbbPer100Hands stat")
		}

		val std = results.computedStat(Stat.STANDARD_DEVIATION)
		if (std != null) {
			assertEquals(200.0, std.value, delta)
		} else {
			Assert.fail("No std stat")
		}

		val stdHourly = results.computedStat(Stat.STANDARD_DEVIATION_HOURLY)
		if (stdHourly != null) {
			assertEquals(111.8, stdHourly.value, delta)
		} else {
			Assert.fail("No stdHourly stat")
		}

		val std100 = results.computedStat(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS)
		if (std100 != null) {
			assertEquals(497.54, std100.value, delta)
		} else {
			Assert.fail("No std100 stat")
		}

		results.computedStat(Stat.MAXIMUM_NETRESULT)?.let {
			assertEquals(300.0, it.value, delta)
		} ?: run {
			Assert.fail("No MAXIMUM_NETRESULT")
		}

		results.computedStat(Stat.MINIMUM_NETRESULT)?.let {
			assertEquals(-100.0, it.value, delta)
		} ?: run {
			Assert.fail("No MINIMUM_NETRESULT")
		}

		results.computedStat(Stat.MAXIMUM_DURATION)?.let {
			assertEquals(3.0, it.value, delta)
		} ?: run {
			Assert.fail("No MAXIMUM_DURATION")
		}

		results.computedStat(Stat.DAYS_PLAYED)?.let {
			assertEquals(2.0, it.value, delta)
		} ?: run {
			Assert.fail("No DAYS_PLAYED")
		}

		results.computedStat(Stat.LOCATIONS_PLAYED)?.let {
			assertEquals(1.0, it.value, delta)
		} ?: run {
			Assert.fail("No LOCATIONS_PLAYED")
		}

		results.computedStat(Stat.LONGEST_STREAKS)?.let {
			assertEquals(1.0, it.value, delta)
			assertEquals(1.0, it.secondValue!!, delta)
		} ?: run {
			Assert.fail("No LOCATIONS_PLAYED")
		}
	}

	@Test
	fun testOverlappingSessions1() {

		val realm = this.mockRealm

		realm.executeTransaction {

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

			val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

			val sd1 = sdf.parse("01/1/2019 09:00")
			val ed1 = sdf.parse("01/1/2019 10:00")
			val sd2 = sdf.parse("01/1/2019 08:00")
			val ed2 = sdf.parse("01/1/2019 11:00")

			s1.startDate = sd1
			s1.endDate = ed1
			s2.startDate = sd2
			s2.endDate = ed2

			// netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800
			// netDuration = 4h, hourly = 100, bb100 = 150 / 75 * 100 = +200

		}

		val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE)
		val group = ComputableGroup(Query(), stats)

		val options = Calculator.Options()
		options.stats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)

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

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

		val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
		if (numberOfSets != null) {
			assertEquals(1, numberOfSets.value.toInt())
		} else {
			Assert.fail("No numberOfSets stat")
		}

		val numberOfGames = results.computedStat(Stat.NUMBER_OF_GAMES)
		if (numberOfGames != null) {
			assertEquals(2, numberOfGames.value.toInt())
		} else {
			Assert.fail("No numberOfSets stat")
		}
	}

	@Test
	fun testOverlappingSessions2() {

		val realm = this.mockRealm
		realm.beginTransaction()

		val s1 = newSessionInstance(realm)
		val s2 = newSessionInstance(realm)
		val s3 = newSessionInstance(realm)

		realm.insert(s1)
		realm.insert(s2)
		realm.insert(s3)

		val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

		val sd1 = sdf.parse("01/1/2019 05:00")
		val ed1 = sdf.parse("01/1/2019 09:00") // 4h
		val sd2 = sdf.parse("01/1/2019 07:00")
		val ed2 = sdf.parse("01/1/2019 11:00") // 4h
		val sd3 = sdf.parse("01/1/2019 03:00")
		val ed3 = sdf.parse("01/1/2019 06:00") // 3h

		s1.startDate = sd1
		s1.endDate = ed1
		s2.startDate = sd2
		s2.endDate = ed2
		s3.startDate = sd3
		s3.endDate = ed3

		realm.copyToRealmOrUpdate(s1)
		realm.copyToRealmOrUpdate(s2)
		realm.copyToRealmOrUpdate(s3)

		realm.commitTransaction()

		val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE)
		val group = ComputableGroup(Query(), stats)

		val options = Calculator.Options()
		options.stats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)

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

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

		val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
		if (numberOfSets != null) {
			assertEquals(1, numberOfSets.value.toInt())
		} else {
			Assert.fail("No numberOfSets stat")
		}

		val numberOfGames = results.computedStat(Stat.NUMBER_OF_GAMES)
		if (numberOfGames != null) {
			assertEquals(3, numberOfGames.value.toInt())
		} else {
			Assert.fail("No numberOfSets stat")
		}

	}

	private var sessions: RealmResults<Session>? = null

	//    @Test
	fun testOverlappingSessionDeletion() {

		val realm = this.mockRealm
		this.sessions = realm.where(Session::class.java).findAll() // monitor session deletions

		this.sessions?.addChangeListener { _, changeSet ->

			val deletedSessions =
				realm.where(Session::class.java).`in`("id", changeSet.deletions.toTypedArray()).findAll()
			deletedSessions.forEach { it.cleanup() }

		}

		realm.beginTransaction()

		val s1 = realm.createObject(Session::class.java, "1")
		val s2 = realm.createObject(Session::class.java, "2")
		val s3 = realm.createObject(Session::class.java, "3")

		realm.insert(s1)
		realm.insert(s2)
		realm.insert(s3)
		realm.commitTransaction()

		val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

		val sd1 = sdf.parse("01/1/2019 05:00")
		val ed1 = sdf.parse("01/1/2019 09:00")
		val sd2 = sdf.parse("01/1/2019 07:00")
		val ed2 = sdf.parse("01/1/2019 11:00")
		val sd3 = sdf.parse("01/1/2019 03:00")
		val ed3 = sdf.parse("01/1/2019 06:00")

		realm.beginTransaction()

		s1.startDate = sd1
		s1.endDate = ed1
		s2.startDate = sd2
		s2.endDate = ed2
		s3.startDate = sd3
		s3.endDate = ed3

		realm.copyToRealmOrUpdate(s1)
		realm.copyToRealmOrUpdate(s2)
		realm.copyToRealmOrUpdate(s3)

		realm.commitTransaction()

		val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE)
		val group = ComputableGroup(Query(), stats)

		val options = Calculator.Options()
		options.stats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)

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

		val duration = results.computedStat(Stat.HOURLY_DURATION)
		if (duration != null) {
			assertEquals(8.0, duration.value, delta)
		} else {
			Assert.fail("No netDuration stat")
		}

		realm.executeTransaction {
			s1.deleteFromRealm()
		}

		val stats2: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE)
		val group2 = ComputableGroup(Query(), stats2)

		val results2: ComputedResults = Calculator.compute(realm, group2, options)

		val duration2 = results2.computedStat(Stat.HOURLY_DURATION)
		if (duration2 != null) {
			assertEquals(7.0, duration2.value, delta)
		} else {
			Assert.fail("No duration2 stat")
		}

	}


	@Test
	fun testSessionSetCount() {

		val realm = this.mockRealm

		realm.beginTransaction()
		val s1 = newSessionInstance(realm)
		realm.insert(s1)

		val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

		val sd1 = sdf.parse("01/1/2019 09:00")
		val ed1 = sdf.parse("01/1/2019 10:00")

		s1.startDate = sd1 //netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800
		s1.endDate = ed1

		realm.copyToRealmOrUpdate(s1)
		realm.commitTransaction()

		val sets = realm.where(SessionSet::class.java).findAll()

		assertEquals(1, sets.size)

		val set = sets.first()
		if (set != null) {
			assertEquals(sd1.time, set.startDate.time)
			assertEquals(ed1.time, set.endDate.time)
		} else {
			Assert.fail("No set")
		}

	}

	@Test
	fun testSessionSetCount2() {

		val realm = this.mockRealm

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

		realm.insert(s1)
		realm.insert(s2)

		val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

		val sd1 = sdf.parse("01/1/2019 09:00")
		val ed1 = sdf.parse("01/1/2019 10:00")
		val sd2 = sdf.parse("01/2/2018 09:00")
		val ed2 = sdf.parse("01/2/2018 10:00")

		s1.startDate = sd1
		s1.endDate = ed1

		s2.startDate = sd2
		s2.endDate = ed2

		realm.copyToRealmOrUpdate(s1)
		realm.copyToRealmOrUpdate(s2)

		realm.commitTransaction()

		val sets = realm.where(SessionSet::class.java).findAll()

		assertEquals(2, sets.size)

	}

	@Test
	fun testSessionRestartInOverlappingSessions() {

		val realm = this.mockRealm
		realm.beginTransaction()

		val s1 = newSessionInstance(realm)
		val s2 = newSessionInstance(realm)
		val s3 = newSessionInstance(realm)

		realm.insert(s1)
		realm.insert(s2)
		realm.insert(s3)

		val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

		val sd1 = sdf.parse("01/1/2019 05:00")
		val ed1 = sdf.parse("01/1/2019 09:00") // 4h
		val sd2 = sdf.parse("01/1/2019 07:00")
		val ed2 = sdf.parse("01/1/2019 11:00") // 4h
		val sd3 = sdf.parse("01/1/2019 03:00")
		val ed3 = sdf.parse("01/1/2019 06:00") // 3h

		s1.startDate = sd1
		s1.endDate = ed1
		s2.startDate = sd2
		s2.endDate = ed2
		s3.startDate = sd3
		s3.endDate = ed3

		realm.copyToRealmOrUpdate(s1)
		realm.copyToRealmOrUpdate(s2)
		realm.copyToRealmOrUpdate(s3)

		realm.commitTransaction()

		realm.executeTransaction {
			s1.endDate = null
		}

		val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE)
		val group = ComputableGroup(Query(), stats)

		val options = Calculator.Options()
//		options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)

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

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

		val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
		if (numberOfSets != null) {
			assertEquals(2, numberOfSets.value.toInt())
		} else {
			Assert.fail("No numberOfSets stat")
		}

	}


//	@Test
	fun testRatedNetResultSessions() {

		val realm = this.mockRealm
		realm.executeTransaction {

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

			val b1 = realm.createObject(Bankroll::class.java, "1")
			val b2 = 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.5
			c2.rate = 1.0
			b1.currency = c1
			b2.currency = c2
			s1.bankroll = b1
			s2.bankroll = b2
			s1.result?.netResult = 100.0
			s2.result?.netResult = 200.0

		}

		val stats: List<Stat> = listOf(Stat.NET_RESULT)
		val group = ComputableGroup(Query(), stats)
		val options = Calculator.Options()
		val results: ComputedResults = Calculator.compute(realm, group, options)

		val netResult = results.computedStat(Stat.NET_RESULT)
		assertEquals(250.0, netResult?.value)
	}

//	@Test
	fun testUpdateRatedNetResultSessions() {

		val realm = this.mockRealm

		realm.executeTransaction {

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

			val b1 = realm.createObject(Bankroll::class.java, "1")
			val b2 = 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.5
			c2.rate = 1.0
			b1.currency = c1
			b2.currency = c2
			s1.bankroll = b1
			s2.bankroll = b2
			s1.result?.netResult = 100.0
			s2.result?.netResult = 200.0

		}

		val stats: List<Stat> = listOf(Stat.NET_RESULT)
		val group = ComputableGroup(Query(), stats)
		val options = Calculator.Options()
		val results: ComputedResults = Calculator.compute(realm, group, options)

		val netResult = results.computedStat(Stat.NET_RESULT)
		assertEquals(250.0, netResult?.value)

		println("currency set rate real test starts here")

		val updatedC2 = realm.where(Currency::class.java).equalTo("id", "2").findFirst()
		updatedC2?.let { currency ->
			val newC2 = realm.copyFromRealm(currency)
			newC2.rate = 3.0
			realm.executeTransaction {
				it.copyToRealmOrUpdate(newC2)
			}
		}

		val updatedGroup = ComputableGroup(Query(), stats)
		val updatedResults: ComputedResults = Calculator.compute(realm, updatedGroup, options)
		val updatedNetResult = updatedResults.computedStat(Stat.NET_RESULT)
		assertEquals(650.0, updatedNetResult?.value)

	}

	@Test
	fun testDaysPlayed() {

		val realm = this.mockRealm

		realm.executeTransaction {

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

			val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

			val sd1 = sdf.parse("01/1/2019 09:00")
			val ed1 = sdf.parse("01/1/2019 10:00")
			val sd2 = sdf.parse("01/1/2019 19:00")
			val ed2 = sdf.parse("01/1/2019 20:00")

			s1.startDate = sd1
			s1.endDate = ed1

			s2.startDate = sd2
			s2.endDate = ed2
		}

		val group = ComputableGroup(Query(), listOf())
		val options = Calculator.Options(stats = listOf(Stat.DAYS_PLAYED))
		val report = Calculator.computeGroups(realm, listOf(group), options)

		report.results.firstOrNull()?.computedStat(Stat.DAYS_PLAYED)?.let {
			assertEquals(1, it.value.toInt())
		} ?: run {
			Assert.fail("Missing DAYS_PLAYED")
		}

	}

	@Test
	fun testFilteredHourlyRate() {

		val realm = this.mockRealm

		realm.executeTransaction {

			val s1 = newSessionInstance(realm, true)
			val s2 = newSessionInstance(realm, true)
			val s3 = newSessionInstance(realm, false)

			val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

			val sd1 = sdf.parse("01/1/2019 09:00")
			val ed1 = sdf.parse("01/1/2019 10:00")
			val sd2 = sdf.parse("01/1/2019 04:00")
			val ed2 = sdf.parse("01/1/2019 05:00")
			val sd3 = sdf.parse("01/1/2019 03:00")
			val ed3 = sdf.parse("01/1/2019 11:00")

			s1.startDate = sd1
			s1.endDate = ed1
			s2.startDate = sd2
			s2.endDate = ed2
			s3.startDate = sd3
			s3.endDate = ed3

		}

		val group = ComputableGroup(Query(QueryCondition.IsCash))

		val options = Calculator.Options()
		options.stats = listOf(Stat.HOURLY_DURATION)

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

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

	@Test
	fun testFilteredHourlyRate2() {

		val realm = this.mockRealm

		realm.executeTransaction {

			val s1 = newSessionInstance(realm, true)
			val s2 = newSessionInstance(realm, true)
			val s3 = newSessionInstance(realm, false)

			val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")

			val sd1 = sdf.parse("01/1/2019 06:00")
			val ed1 = sdf.parse("01/1/2019 09:00")
			val sd2 = sdf.parse("01/1/2019 07:00")
			val ed2 = sdf.parse("01/1/2019 10:00")
			val sd3 = sdf.parse("01/1/2019 03:00")
			val ed3 = sdf.parse("01/1/2019 11:00")

			s1.startDate = sd1
			s1.endDate = ed1
			s2.startDate = sd2
			s2.endDate = ed2
			s3.startDate = sd3
			s3.endDate = ed3

		}

		val group = ComputableGroup(Query(QueryCondition.IsCash))

		val options = Calculator.Options()
		options.stats = listOf(Stat.HOURLY_DURATION)

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

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

}