from pathlib import Path
import fetchx.ioutils as ioutils
import re


class DocTsFormula(dict):
    def __init__(self, *args, **kwargs):
        """
        Represents a Time Series Formula in the metamodel.
        Inherits from dict to store formula properties.
        """
        super().__init__(*args, **kwargs)
        self.tsdefinition = None

    @staticmethod
    def load_from_directory(tsformulas_path: Path) -> dict[str, 'DocTsFormula']:
        """
        Load all Time Series Formulas from the specified directory.
        :param tsformulas_path: Base path where the metamodel is located.
        :return: A dictionary mapping formula codes to DocTsFormula instances.
        """
        result = {}
        tsformulas_path = tsformulas_path / "calc/tsFormula"
        # Load all .json files
        files, directories = ioutils.search_folder(str(tsformulas_path.resolve()), list_of_extensions=[".json"])
        for file in files:
            value = ioutils.load_json(file)
            code = Path(file).stem
            result[code] = DocTsFormula(value)
        return result
    
    def parse_formula_words(self) -> list[str]:
        """
        Parse the formula and return a list of words (alphanumeric sequences and underscores).
        This is a simple parser that does not handle comments or functions.
        """
        formula = str(self.get("formula", ""))
        formula += " "  # add space at the end to capture last word
        words = []
        current_word = ""
        started_with_at = False
        for letter in formula:
            if letter.isalnum() or letter == '_':
                current_word += letter
            elif letter == '-' and started_with_at:
                current_word += letter
            elif letter == '@' and not current_word:
                current_word += letter
                started_with_at = True
            else:
                # add current word to list if exists
                if current_word:
                    if started_with_at:
                        words.append(current_word[1:])  # remove @ at the beginning
                    else:
                        words.append(current_word)
                # reset current word
                current_word = ""
                started_with_at = False
        return words
    
    def parse_formula_words2(self) -> list[str]:
        """
        Parse the formula and return a list of words (alphanumeric sequences and underscores).
        This is a simple parser that does not handle comments or functions.
        """
        # TODO process comments in formulas and ignore them
        formula = str(self.get("formula", ""))
        # Find all words (sequences of alphanumeric characters and underscores)
        words = re.findall(r'\b\w+\b', formula)
        # remove @ at the beginning of words if exists
        words = [word[1:] if word.startswith('@') else word for word in words]
        return words
        