#!/usr/bin/env python3
"""Safely add the Codex usage module to an existing Waybar JSONC config."""

from __future__ import annotations

import argparse
import re
import shutil
import sys
from datetime import datetime
from pathlib import Path

MODULE_NAME = "custom/codex-usage"
MODULE_BLOCK = '''  "custom/codex-usage": {
    "exec": "codex-waybar",
    "return-type": "json",
    "interval": 60,
    "tooltip": true
  }
'''
CSS_BLOCK = """

/* Codex usage module */
#custom-codex-usage {
  min-width: 12px;
  margin: 0 7.5px;
}

#custom-codex-usage.warning {
  color: #d8a657;
}

#custom-codex-usage.critical,
#custom-codex-usage.unavailable {
  color: #a55555;
}

#custom-codex-usage.stale {
  opacity: 0.65;
}
"""


class ConfigureError(RuntimeError):
    pass


def backup(path: Path) -> Path:
    stamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    destination = path.with_name(f"{path.name}.bak.{stamp}")
    shutil.copy2(path, destination)
    return destination


def insert_module_reference(text: str, section: str) -> str:
    pattern = re.compile(rf'("modules-{section}"\s*:\s*\[)(.*?)(\])', re.DOTALL)
    matches = list(pattern.finditer(text))
    if len(matches) != 1:
        raise ConfigureError(f'Could not uniquely locate "modules-{section}"')
    match = matches[0]
    if f'"{MODULE_NAME}"' in match.group(2):
        return text
    return text[: match.end(1)] + f'"{MODULE_NAME}", ' + text[match.end(1) :]


def insert_module_block(text: str) -> str:
    if re.search(rf'"{re.escape(MODULE_NAME)}"\s*:', text):
        return text
    close = text.rfind("}")
    if close < 0:
        raise ConfigureError("Could not locate the top-level closing brace")
    before = text[:close].rstrip()
    comma = "" if before.endswith("{") else ","
    return f"{before}{comma}\n{MODULE_BLOCK}{text[close:]}"


def configure(config_path: Path, style_path: Path, section: str) -> tuple[Path | None, Path | None]:
    if not config_path.is_file():
        raise ConfigureError(f"Waybar config not found: {config_path}")
    original = config_path.read_text()
    updated = insert_module_block(insert_module_reference(original, section))
    config_backup = None
    if updated != original:
        config_backup = backup(config_path)
        config_path.write_text(updated)

    style_backup = None
    if style_path.exists():
        style = style_path.read_text()
        if "#custom-codex-usage" not in style:
            style_backup = backup(style_path)
            style_path.write_text(style.rstrip() + CSS_BLOCK)
    else:
        style_path.parent.mkdir(parents=True, exist_ok=True)
        style_path.write_text(CSS_BLOCK.lstrip())
    return config_backup, style_backup


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description=__doc__)
    default_dir = Path.home() / ".config" / "waybar"
    parser.add_argument("--section", choices=("left", "center", "right"), required=True)
    parser.add_argument("--config", type=Path, default=default_dir / "config.jsonc")
    parser.add_argument("--style", type=Path, default=default_dir / "style.css")
    return parser.parse_args()


def main() -> int:
    args = parse_args()
    try:
        config_backup, style_backup = configure(args.config, args.style, args.section)
    except (OSError, ConfigureError) as exc:
        print(f"codex-waybar-configure: {exc}", file=sys.stderr)
        return 1
    print(f"Configured {args.config}")
    if config_backup:
        print(f"Backup: {config_backup}")
    if style_backup:
        print(f"Backup: {style_backup}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
