from __future__ import annotations

from dataclasses import dataclass


class PackageConfigError(Exception):
    pass


@dataclass(frozen=True)
class PackageConfig:
    entry: str
    dependencies: dict[str, str]

    @property
    def dependency_names(self) -> list[str]:
        return list(self.dependencies.keys())


def _strip_comment(line: str) -> str:
    # minimal TOML-style comment stripping (does not handle # inside strings)
    for ch in ("#",):
        idx = line.find(ch)
        if idx != -1:
            return line[:idx]
    return line


def _parse_string(value: str) -> str:
    value = value.strip()
    if len(value) >= 2 and value[0] == value[-1] and value[0] in ('"', "'"):
        return value[1:-1]
    raise PackageConfigError(f"Expected string value, got: {value}")


def _parse_string_list(value: str) -> list[str]:
    v = value.strip()
    if not (v.startswith("[") and v.endswith("]")):
        raise PackageConfigError(f"Expected list value, got: {value}")
    inner = v[1:-1].strip()
    if inner == "":
        return []

    items: list[str] = []
    current = ""
    in_quote: str | None = None
    escape = False
    for ch in inner:
        if escape:
            current += ch
            escape = False
            continue
        if ch == "\\" and in_quote is not None:
            escape = True
            current += ch
            continue
        if ch in ('"', "'"):
            if in_quote is None:
                in_quote = ch
            elif in_quote == ch:
                in_quote = None
            current += ch
            continue
        if ch == "," and in_quote is None:
            items.append(_parse_string(current))
            current = ""
            continue
        current += ch

    if in_quote is not None:
        raise PackageConfigError("Unterminated string in list")
    items.append(_parse_string(current))
    return [s for s in (i.strip() for i in items) if s != ""]


def load_package_config(toml_text: str) -> PackageConfig:
    section = None
    package: dict[str, str] = {}
    deps_list: list[str] = []
    deps_table: dict[str, str] = {}

    for raw in toml_text.splitlines():
        line = _strip_comment(raw).strip()
        if not line:
            continue

        if line.startswith("[") and line.endswith("]"):
            section = line[1:-1].strip()
            continue

        if "=" not in line:
            continue
        key, value = line.split("=", 1)
        key = key.strip()
        value = value.strip()

        if section == "package":
            if key in ("name", "version", "entry"):
                package[key] = _parse_string(value)
            elif key == "dependencies":
                deps_list = _parse_string_list(value)
        elif section == "dependencies":
            deps_table[key] = _parse_string(value)

    entry = package.get("entry")
    if not entry:
        raise PackageConfigError("Missing [package].entry in prasad.toml")

    # Backward compatible behavior:
    # - Prefer [dependencies] table when present
    # - Otherwise allow [package].dependencies = ["mod1", "mod2"]
    if deps_table:
        deps = deps_table
    else:
        deps = {name: "*" for name in deps_list}

    return PackageConfig(entry=entry, dependencies=deps)
