package ru.dbotthepony.mc.otm.tests

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import ru.dbotthepony.mc.otm.core.util.getLevelFromXp
import ru.dbotthepony.mc.otm.core.util.getTotalXpRequiredForLevel
import ru.dbotthepony.mc.otm.core.util.getXpRequiredForLevelUp

object ExperienceUtilsTest {
	@Test
	@DisplayName("Experience utils xp required for level up")
	fun levelUp() {
		var i = 0
		assertEquals(7L, getXpRequiredForLevelUp(i++))
		assertEquals(9L, getXpRequiredForLevelUp(i++))
		assertEquals(11L, getXpRequiredForLevelUp(i++))
		assertEquals(13L, getXpRequiredForLevelUp(i++))
		assertEquals(15L, getXpRequiredForLevelUp(i++))
		assertEquals(17L, getXpRequiredForLevelUp(i++))
		assertEquals(19L, getXpRequiredForLevelUp(i++))
		assertEquals(21L, getXpRequiredForLevelUp(i++))
		assertEquals(23L, getXpRequiredForLevelUp(i++))
		assertEquals(25L, getXpRequiredForLevelUp(i++))
		assertEquals(27L, getXpRequiredForLevelUp(i++))
		assertEquals(29L, getXpRequiredForLevelUp(i++))
		assertEquals(31L, getXpRequiredForLevelUp(i++))
		assertEquals(33L, getXpRequiredForLevelUp(i++))
		assertEquals(35L, getXpRequiredForLevelUp(i++))
		assertEquals(37L, getXpRequiredForLevelUp(i++))
		assertEquals(42L, getXpRequiredForLevelUp(i++))
		assertEquals(47L, getXpRequiredForLevelUp(i++))
		assertEquals(52L, getXpRequiredForLevelUp(i++))
		assertEquals(57L, getXpRequiredForLevelUp(i++))
		assertEquals(62L, getXpRequiredForLevelUp(i++))
		assertEquals(67L, getXpRequiredForLevelUp(i++))
		assertEquals(72L, getXpRequiredForLevelUp(i++))
		assertEquals(77L, getXpRequiredForLevelUp(i++))
		assertEquals(82L, getXpRequiredForLevelUp(i++))
		assertEquals(87L, getXpRequiredForLevelUp(i++))
		assertEquals(92L, getXpRequiredForLevelUp(i++))
		assertEquals(97L, getXpRequiredForLevelUp(i++))
		assertEquals(102L, getXpRequiredForLevelUp(i++))
		assertEquals(107L, getXpRequiredForLevelUp(i++))
		assertEquals(112L, getXpRequiredForLevelUp(i++))
		assertEquals(121L, getXpRequiredForLevelUp(i++))
		assertEquals(130L, getXpRequiredForLevelUp(i++))
		assertEquals(139L, getXpRequiredForLevelUp(i++))
		assertEquals(148L, getXpRequiredForLevelUp(i++))
		assertEquals(157L, getXpRequiredForLevelUp(i++))
		assertEquals(166L, getXpRequiredForLevelUp(i++))
		assertEquals(175L, getXpRequiredForLevelUp(i++))
		assertEquals(184L, getXpRequiredForLevelUp(i++))
		assertEquals(193L, getXpRequiredForLevelUp(i++))
	}

	@Test
	@DisplayName("Experience utils total xp required for level")
	fun totalXp() {
		var i = 1
		assertEquals(7L, getTotalXpRequiredForLevel(i++)) // 1
		assertEquals(16L, getTotalXpRequiredForLevel(i++)) // 2
		assertEquals(27L, getTotalXpRequiredForLevel(i++)) // 3
		assertEquals(40L, getTotalXpRequiredForLevel(i++)) // 4
		assertEquals(55L, getTotalXpRequiredForLevel(i++)) // 5
		assertEquals(72L, getTotalXpRequiredForLevel(i++)) // 6
		assertEquals(91L, getTotalXpRequiredForLevel(i++)) // 7
		assertEquals(112L, getTotalXpRequiredForLevel(i++)) // 8
		assertEquals(135L, getTotalXpRequiredForLevel(i++)) // 9
		assertEquals(160L, getTotalXpRequiredForLevel(i++)) // 10
		assertEquals(187L, getTotalXpRequiredForLevel(i++)) // 11
		assertEquals(216L, getTotalXpRequiredForLevel(i++)) // 12
		assertEquals(247L, getTotalXpRequiredForLevel(i++)) // 13
		assertEquals(280L, getTotalXpRequiredForLevel(i++)) // 14
		assertEquals(315L, getTotalXpRequiredForLevel(i++)) // 15
		assertEquals(352L, getTotalXpRequiredForLevel(i++)) // 16
		assertEquals(394L, getTotalXpRequiredForLevel(i++)) // 17
		assertEquals(441L, getTotalXpRequiredForLevel(i++)) // 18
		assertEquals(493L, getTotalXpRequiredForLevel(i++)) // 19
		assertEquals(550L, getTotalXpRequiredForLevel(i++)) // 20
		assertEquals(612L, getTotalXpRequiredForLevel(i++)) // 21
		assertEquals(679L, getTotalXpRequiredForLevel(i++)) // 22
		assertEquals(751L, getTotalXpRequiredForLevel(i++)) // 23
		assertEquals(828L, getTotalXpRequiredForLevel(i++)) // 24
		assertEquals(910L, getTotalXpRequiredForLevel(i++)) // 25
		assertEquals(997L, getTotalXpRequiredForLevel(i++)) // 26
		assertEquals(1089L, getTotalXpRequiredForLevel(i++)) // 27
		assertEquals(1186L, getTotalXpRequiredForLevel(i++)) // 28
		assertEquals(1288L, getTotalXpRequiredForLevel(i++)) // 29
		assertEquals(1395L, getTotalXpRequiredForLevel(i++)) // 30
		assertEquals(1507L, getTotalXpRequiredForLevel(i++)) // 31
		assertEquals(1628L, getTotalXpRequiredForLevel(i++)) // 32
		assertEquals(1758L, getTotalXpRequiredForLevel(i++)) // 33
		assertEquals(1897L, getTotalXpRequiredForLevel(i++)) // 34
		assertEquals(2045L, getTotalXpRequiredForLevel(i++)) // 35
		assertEquals(2202L, getTotalXpRequiredForLevel(i++)) // 36
		assertEquals(2368L, getTotalXpRequiredForLevel(i++)) // 37
		assertEquals(2543L, getTotalXpRequiredForLevel(i++)) // 38
		assertEquals(2727L, getTotalXpRequiredForLevel(i++)) // 39
		assertEquals(2920L, getTotalXpRequiredForLevel(i++)) // 40
	}

	@Test
	@DisplayName("Experience utils reverse search xp -> level")
	fun reverseSearch() {
		assertEquals(0, getLevelFromXp(4L))
		assertEquals(0, getLevelFromXp(6L))
		assertEquals(1, getLevelFromXp(7L))
		assertEquals(1, getLevelFromXp(8L))

		assertEquals(19, getLevelFromXp(540L))
		assertEquals(19, getLevelFromXp(545L))
		assertEquals(20, getLevelFromXp(550L))
		assertEquals(21, getLevelFromXp(551L))
		assertEquals(21, getLevelFromXp(554L))
		assertEquals(21, getLevelFromXp(556L))

		for (i in 50 .. 100) {
			assertEquals(i, getLevelFromXp(getTotalXpRequiredForLevel(i)))
			assertEquals(i - 1, getLevelFromXp(getTotalXpRequiredForLevel(i) - 1L))
			assertEquals(i, getLevelFromXp(getTotalXpRequiredForLevel(i) + 1L))
		}
	}
}
