import json
import unittest
import requests

import compLib.Seeding as Seeding
import compLib.Api as SeedingApi
import compLib.DoubleElimination as De


class SeedingTest(unittest.TestCase):
    def test_basic_seed(self):
        gamestate = Seeding.Gamestate(0)
        self.assertEqual(gamestate.seed, 0)
        self.assertEqual(gamestate.heu_color, 1)
        self.assertEqual(gamestate.get_heuballen(), 1)
        self.assertEqual(gamestate.get_logistic_plan(),
                         [12, 13, 10, 13, 12, 10, 11, 10, 12, 11, 12, 13, 10, 12, 10, 11, 13, 11, 13, 11, 12])
        self.assertEqual(gamestate.get_material_deliveries(), [[3, 1], [0, 3], [3, 1], [3, 1]])


def util_get_info():
    res = requests.get(SeedingApi.CONF_URL + "getInfo")
    return json.loads(res.text)


def util_set_seeding():
    res = requests.get(SeedingApi.CONF_URL + "setToSeeding")
    return res.status_code == 200


def util_set_de():
    res = requests.get(SeedingApi.CONF_URL + "setToDoubleElim")
    return res.status_code == 200


def util_start_match():
    res = requests.get(SeedingApi.CONF_URL + "startMatch")
    return res.status_code == 200


def util_reset_state():
    res = requests.get(SeedingApi.CONF_URL + "resetState")
    return res.status_code == 200


def util_set_seed(seed):
    res = requests.get(SeedingApi.CONF_URL + "resetState", params={"seed": seed})
    return res.status_code == 200


class SeedingApiTest(unittest.TestCase):
    def test_api_seeding_extensive(self):
        self.assertTrue(util_set_seeding())
        self.assertTrue(util_get_info()["is_seeding"])
        for seed in range(0, 256):
            print(f"Testing seed: {seed}")
            gamestate = Seeding.Gamestate(seed)
            self.assertTrue(util_set_seed(seed))
            seeding_api = SeedingApi.Seeding()
            self.assertEqual(seeding_api.get_heuballen(), gamestate.get_heuballen())
            self.assertEqual(seeding_api.get_logistic_plan(), gamestate.get_logistic_plan())
            self.assertEqual(seeding_api.get_material_deliveries(), gamestate.get_material_deliveries())


class DeApiTest(unittest.TestCase):
    def test_api_de(self):
        self.assertTrue(util_set_de())
        self.assertTrue(util_reset_state())
        self.assertFalse(util_get_info()["is_seeding"])

        de = De.DoubleElim()
        self.assertEqual(de.get_pos(), (De.Position(0, 0, -1), 503))
        self.assertEqual(de.get_opponent(), (De.Position(0, 0, -1), 503))
        self.assertEqual(de.get_goal(), (De.Position(0, 0, -1), 503))
        self.assertEqual(de.get_items(), ([], 503))
        self.assertEqual(de.get_scores(), ({"self": 0, "opponent": 0}, 503))

        self.assertTrue(util_start_match())
        self.assertLessEqual(util_get_info()["timeleft"], 120)

        self.assertEqual(de.get_pos()[1], 200)
        self.assertEqual(de.get_opponent()[1], 200)
        self.assertEqual(de.get_goal()[1], 200)
        self.assertEqual(de.get_items()[1], 200)
        self.assertEqual(de.get_scores()[1], 200)

        self.assertTrue(0 <= de.get_pos()[0].x <= 250)
        self.assertTrue(0 <= de.get_pos()[0].y <= 250)
        self.assertTrue(0 <= de.get_pos()[0].degrees <= 360)
        self.assertEqual(de.get_items(), ([], 200))

        self.assertTrue(util_reset_state())



if __name__ == '__main__':
    unittest.main()
