import unittest
from snakes.MasterSnake import MasterSnake

class TestMasterSnake(unittest.TestCase):
    def setUp(self):
        self.snake = MasterSnake()
        self.game_data = {
            "board": {
                "height": 11,
                "width": 11,
                "snakes": [
                    {
                        "id": "snake-1",
                        "body": [
                            {"x": 0, "y": 0},
                            {"x": 1, "y": 0},
                            {"x": 2, "y": 0}
                        ],
                        "head": {"x": 2, "y": 1},
                    },
                    {
                        "id": "snake-2",
                        "body": [
                            {"x": 5, "y": 4},
                            {"x": 5, "y": 3},
                            {"x": 6, "y": 3},
                            {"x": 6, "y": 2}
                        ],
                        "head": {"x": 6, "y": 3},
                    }
                ],
                "food": [
                    {
                        "x": 2,
                        "y": 0
                    },
                    {
                        "x": 10,
                        "y": 8
                    },
                    {
                        "x": 5,
                        "y": 5
                    }
                ],
            },
            "you": {
                "id": "snake-1",
                "body": [
                    {"x": 0, "y": 0},
                    {"x": 1, "y": 0},
                    {"x": 2, "y": 0}
                ],
                "head": {"x": 0, "y": 0},
            }
        }

    def test_avoid_snake_body(self):
        snakes = self.game_data['board']['snakes']
        board_width = self.game_data['board']['width']
        board_height = self.game_data['board']['height']
        safe_positions = self.snake.avoid_snake_body(snakes, board_width, board_height)
        self.assertIsInstance(safe_positions, list)
        self.assertTrue(all(isinstance(pos, dict) for pos in safe_positions))
        self.assertTrue(all('x' in pos and 'y' in pos for pos in safe_positions))

    def test_find_safe_positions(self):
        body_positions = {(0, 0), (1, 0), (2, 0), (5, 4), (5, 3), (6, 3), (6, 2)}
        safe_positions = self.snake.find_safe_positions(body_positions, 11, 11)
        self.assertNotIn({'x': 0, 'y': 0}, safe_positions)
        self.assertIn({'x': 10, 'y': 10}, safe_positions)

    def test_choose_move(self):
        move = self.snake.choose_move(self.game_data)
        self.assertIn(move, ["up", "down", "left", "right"])

    def test_move_towards_food(self):
        head = {'x': 0, 'y': 0}
        food = (5, 5)
        safe_positions = [{'x': 1, 'y': 0}, {'x': 0, 'y': 1}, {'x': 1, 'y': 1}]
        direction = self.snake.move_towards_food(head, food, safe_positions)
        self.assertIn(direction, ["up", "down", "left", "right"])

    def test_find_path_to_food(self):
        path = self.snake.find_path_to_food(self.game_data)
        print(path)
        self.assertIsInstance(path, list)
        self.assertTrue(all(isinstance(pos, dict) for pos in path))
        self.assertTrue(all('x' in pos and 'y' in pos for pos in path))

    def test_find_direction(self):
        head = {'x': 0, 'y': 0}
        safe_positions = [{'x': 1, 'y': 0}, {'x': 0, 'y': 1}, {'x': 1, 'y': 1}]
        direction = self.snake.find_direction(head, safe_positions)
        self.assertIn(direction, ["up", "down", "left", "right"])

    def test_avoid_dead_ends(self):
        head = {'x': 0, 'y': 0}
        move = "right"
        board_width = 11
        board_height = 11
        snakes = self.game_data['board']['snakes']
        safe_positions = [{'x': 1, 'y': 0}, {'x': 0, 'y': 1}, {'x': 1, 'y': 1}]
        new_move = self.snake.avoid_dead_ends(head, move, safe_positions, board_width, board_height, snakes)
        self.assertIn(new_move, ["up", "down", "left", "right"])

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