from abc import ABC, abstractmethod
from maze_model import Cell, Maze


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


class TextFileMazeBuilder(MazeBuilder):
    def build_from_file(self, filename) -> Maze:
        with open(filename, 'r', encoding='utf-8') as f:
            lines = f.read().splitlines()

        width = max(len(line) for line in lines) if lines else 0
        height = len(lines)

        cells = []
        start = None
        exit_cell = None

        for y, line in enumerate(lines):
            row = []
            line = line.ljust(width)
            for x, char in enumerate(line):
                is_wall = (char == '#')
                is_start = (char == 'S')
                is_exit = (char == 'E')
                cell = Cell(x, y, is_wall=is_wall,
                            is_start=is_start, is_exit=is_exit)
                if is_start:
                    start = cell
                if is_exit:
                    exit_cell = cell
                row.append(cell)
            cells.append(row)

        if start is None:
            raise ValueError("В файле лабиринта не найден старт (S)")
        if exit_cell is None:
            raise ValueError("В файле лабиринта не найден выход (E)")

        return Maze(width, height, cells, start, exit_cell)
