#!/usr/bin/env python3

from __future__ import annotations

import argparse
import re
from pathlib import Path

ENV_ASSIGNMENT_RE = re.compile(
    r"^(\s*(?:export\s+)?)([A-Za-z_][A-Za-z0-9_]*)(\s*=\s*)(.*)$"
)


def split_inline_comment(rhs: str) -> tuple[str, str]:
    in_single = False
    in_double = False
    escaped = False

    for i, char in enumerate(rhs):
        if escaped:
            escaped = False
            continue

        if char == "\\":
            escaped = True
            continue

        if char == "'" and not in_double:
            in_single = not in_single
            continue

        if char == '"' and not in_single:
            in_double = not in_double
            continue

        if char == "#" and not in_single and not in_double:
            if i == 0 or rhs[i - 1].isspace():
                return rhs[:i], rhs[i:]

    return rhs, ""


def transform_line(line: str) -> str:
    stripped = line.strip()
    if stripped == "" or stripped.startswith("#"):
        return line

    newline = ""
    raw = line
    if line.endswith("\r\n"):
        newline = "\r\n"
        raw = line[:-2]
    elif line.endswith("\n"):
        newline = "\n"
        raw = line[:-1]

    match = ENV_ASSIGNMENT_RE.match(raw)
    if not match:
        return line

    prefix, key, delimiter, rhs = match.groups()
    value_part, comment_part = split_inline_comment(rhs)
    trailing_ws = value_part[len(value_part.rstrip()) :]
    placeholder = f"${{{{project.{key}}}}}"

    return f"{prefix}{key}{delimiter}{placeholder}{trailing_ws}{comment_part}{newline}"


def generate_example_env(source_path: Path, target_path: Path) -> None:
    lines = source_path.read_text(encoding="utf-8").splitlines(keepends=True)
    transformed = [transform_line(line) for line in lines]
    target_path.write_text("".join(transformed), encoding="utf-8")


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Generate .env.example using ${{project.KEY}} placeholders."
    )
    parser.add_argument("--source", default=".env", help="Path to source .env file")
    parser.add_argument(
        "--target", default=".env.example", help="Path to output .env.example file"
    )
    args = parser.parse_args()

    source_path = Path(args.source)
    target_path = Path(args.target)

    if not source_path.exists():
        raise FileNotFoundError(f"Source env file not found: {source_path}")

    generate_example_env(source_path, target_path)


if __name__ == "__main__":
    main()
