from abc import ABC, abstractmethod

from .maze import Maze


class MazeBuilder(ABC):
    @abstractmethod
    def build_from_file(self, filename: str) -> Maze:
        pass


class TextFileMazeBuilder(MazeBuilder):
    def build_from_file(self, filename: str) -> Maze:
        with open(filename, "r", encoding="utf-8") as f:
            lines = [line.rstrip("\n") for line in f.readlines()]
        height = len(lines)
        width = max(len(line) for line in lines) if height > 0 else 0

        start_count = 0
        exit_count = 0
        maze = Maze(width, height)

        for y, line in enumerate(lines):
            for x, ch in enumerate(line):
                if ch == "#":
                    maze.set_cell(x, y, "wall")
                elif ch == "S":
                    maze.set_cell(x, y, "start")
                    start_count += 1
                elif ch == "E":
                    maze.set_cell(x, y, "exit")
                    exit_count += 1
                else:
                    maze.set_cell(x, y, "path")

        if start_count != 1 or exit_count != 1:
            raise ValueError(f"S={start_count}, E={exit_count}")
        return maze
