import re
from pathlib import Path
from typing import TextIO

from .boundary_type import BoundaryType


class BCCheckProvider:
    """Provider class for parsing the bc table check files.

    Parameters
    ----------
    fpath : Path
        Path to the source output check file.
    """

    def __init__(self, fpath: Path):
        #: Path: The path to the source output file.
        self.fpath = Path(fpath)
        #: Path: The path to the TCF file that generated the source file.
        self.tcf = Path()
        #: str: The domain of the check file - i.e. 1D or a 2D check file.
        self.domain = ''
        #: dict: Dictionary of boundaries
        self.database = {}

    def load(self):
        """Loads the boundary condition check file."""
        with self.fpath.open() as f:
            for line in f:
                if line.startswith('Generated by'):
                    self.tcf = self._extract_tcf(line)
                elif re.findall(r'^"?BC\d{6}:\s', line):
                    self.load_boundary(line, f)

        if re.findall(r'_1d_bc_tables_check', self.fpath.stem):
            self.domain = '1d'
        elif re.findall(r'_2d_bc_tables_check', self.fpath.stem):
            self.domain = '2d'

    def load_boundary(self, line: str, fo: TextIO):
        """Load the boundary starting at the given line from the open file object.

        Parameters
        ----------
        line : str
            Starting line of the boundary to be loaded.
        fo : TextIO
            Open file object to read the boundary from.
        """
        bndry = BoundaryType(line)
        if not bndry.valid:
            return
        bndry.read(fo)
        self.database[bndry.id] = bndry

    def name2bcid(self, name: str) -> str:
        """Return boundary condition ID from name.

        Parameters
        ----------
        name : str
            Boundary condition name.

        Returns
        -------
        str
            Boundary condition ID.
        """
        for id_, bndry in self.database.items():
            if name == bndry.name:
                return id_
        return ''

    @staticmethod
    def _extract_tcf(line: str) -> Path:
        tcf = re.findall(r'".*"', line)
        if tcf:
            tcf = tcf[0].strip('"')
            return Path(tcf)
        return Path()
