import re
from typing import Dict, Literal

from pydantic import BaseModel, StrictBool, StrictStr


class BindMount(BaseModel):
    mount_type: Literal["bind"] = "bind"
    target: StrictStr
    source: StrictStr | None = None
    from_source: StrictStr | None = None
    readwrite: StrictBool | None = None

    def to_string(self) -> str:
        mount_string = f"--mount=type={self.mount_type},target={self.target}"

        if self.source:
            mount_string = f"{mount_string},source={self.source}"

        if self.from_source:
            mount_string = f"{mount_string},from={self.from_source}"

        if self.readwrite:
            readwrite_string = "readwrite"
            mount_string = f"{mount_string},{readwrite_string}"

        return mount_string

    @classmethod
    def parse(cls, line: str):
        lines = line.split(" ")
        options: Dict[str, str | bool] = {"mount_type": "bind"}

        if "readwrite" in lines:
            options["readwrite"] = True
            lines.remove("readwrite")

        elif "rw" in lines:
            options["readwrite"] = True
            lines.remove("rw")

        tokens = line.split(",")

        for token in tokens:
            if target := re.search(r"target=(.*)", token):
                options["target"] = re.sub(r"target=", "", target.group(0))

            elif source := re.search(r"source=(.*)", token):
                options["source"] = re.sub(r"source=", "", source.group(0))

            elif mount_from := re.search(r"from=(.*)", token):
                options["from_source"] = re.sub(r"from=", "", mount_from.group(0))

            elif readwrite := re.search(r"readwrite=(.*)", token):
                readwrite_value = re.sub(r"readwrite=", "", readwrite.group(0))
                options["readwrite"] = True if readwrite_value == "true" else None

        return BindMount(**options)
