from __future__ import annotations

from dataclasses import dataclass
from os import setregid
from types import NoneType
from typing import Optional
from result import Result, Ok, Err
from icecream import ic

@dataclass
class Tag:
    value: str
    trail: Optional[str]

    def __post_init__(self) -> None:
        self.trail = self.trail if (self.trail is not None) and (self.trail.strip() != '') else None

    # Returns the type of tag.
    def type(self) -> str:
        type = str()

        for c in self.value:
            if c.isspace():
                break

            type += c


        return type

    def get_param(self, param: str) -> Optional[str]:
        pos = self.value.find(param) + param.__len__() + len('="')

        if pos == -1:
            return None

        param_value = str()

        for idx in range(pos, (self.value.__len__() - param.__len__())):
            param_value += self.value[idx]

        return param_value

    def write(self) -> str:
        return f'<{self.value}>{self.trail if self.trail != None else ''}'

@dataclass
class HTML:
    value: str

    # Returns all tags in order in the html file.
    def tags(self) -> list[Tag]:
        tag = str()
        trail: Optional[str] = str()
        tags = list()
        record = False

        for c in self.value:
            if c == '<' and tag != '':
                tags.append(Tag(tag, trail))
                tag = str()
                trail = str()

            if c == '<' or c == '>':
                record = not record # why can't I have ! operator...
            elif record == True:
                tag += c
            else:
                trail += c

        tags.append(Tag(tag, trail))
        return tags

    def inflate(self) -> Result[str, str]:
        file = str()

        for tag in self.tags():
            if tag.type() == 'include':
                chunk = tag.get_param('src')
                if isinstance(chunk, NoneType):
                    return Err('FileNotFoundError')

                html = HTML(open(chunk, 'rt').read())
                file += html.inflate().expect('FileNotFoundError')
            else:
                file += tag.write()

        return Ok(file)

    # Convert the HTML obj into a str to write to file.
    def write(self) -> str:
        return self.value

def run() -> None:
    with open('/home/cutieguwu/Workspace/balloon/tests/src/index.html', 'rt') as f:
        html_src = HTML(f.read())
    with open('/home/cutieguwu/Workspace/balloon/target/index.html', 'w') as f:
        f.write(html_src.write())

if __name__ == '__main__':
    run()
