from task2.mazeBuilder import MazeBuilder
from task2.mazeObjects.maze import Maze
from task2.mazeSolver import MazeSolver, SearchStats

from task2.strategyObjects.BFS import BFS
from task2.strategyObjects.DFS import DFS
from task2.strategyObjects.AStar import AStar

import csv
import os

TEST_ITERATIONS = 10

class Tester():
    """Для каждого лабиринта и каждой стратегии запустить solve() 5–10 раз,
    усреднить время, количество посещённых клеток, длину пути.
    Записать результаты в CSV:
    лабиринт,стратегия,время_мс,посещено_клеток,длина_пути."""
    result:list[SearchStats]
    def __init__(self, builder:MazeBuilder, writefile:str):
        self._builder = builder
        self.writefile = "../" + writefile
        
    def setTestingDirectory(self, directory:str):
        if directory[-1] != "/":
            directory += "/"
        self._directory = "../" + directory
    
    def _getMazes(self) -> list[Maze]:
        arr = []
        files = os.listdir(self._directory)
        only_txt_files = [f for f in files if os.path.isfile(os.path.join(self._directory, f)) and os.path.splitext(f)[1] == ".txt"]

        for f in only_txt_files:
            arr.append(self._builder.buildFromFile(os.path.join(self._directory, f)))
        return arr

    def _solveAvg(self, solver: MazeSolver):
        avgtime = 0
        for i in range(TEST_ITERATIONS):
            result = solver.solve()
            # Всё кроме времени будет одинаковым
            avgtime += result.duration/TEST_ITERATIONS
        result.duration = avgtime
        return result

    def saveCSV(self):
        rows = []
        for r in self.result:
            r = r.toDict()
            row = (r["strategy_name"],
                   r["maze_name"],
                   r["duration"],
                   r["visited_cells"],
                   r["path_len"]
            )
            rows.append(row)
        with open(self.writefile, "w", newline="") as f:
            writer = csv.writer(f)
            writer.writerow(["Алгоритм", "Лабиринт", "Время (мс)", "Посещённые клетки", "Длинна пути"])
            writer.writerows(rows)

    def test(self):
        self.result = []
        arr = self._getMazes()
        for algoritm in (BFS, DFS, AStar):
            solver = MazeSolver(algoritm()) # это прикол
            for maze in arr:
                solver.setMaze(maze)
                self.result.append(self._solveAvg(solver))
                self.result[-1].maze_name = maze.name
        return self.result


if __name__ == "__main__":
    exit()
    from task2.mazeBuilder import TextFileMazeBuilder

    builder = TextFileMazeBuilder()
    tester = Tester(builder, "docs/data/task2/results.csv")
    tester.setTestingDirectory("task2/mazeExamples")
    tester.test()
    tester.saveCSV()
    