#!/usr/bin/env python3
from __future__ import annotations
import argparse, re
from pathlib import Path

def valid_identifier(value: str) -> str:
    if not re.fullmatch(r'[A-Za-z][A-Za-z0-9]*', value):
        raise argparse.ArgumentTypeError('Use PascalCase alphanumeric identifiers only.')
    return value

def render_tree(source: Path, target: Path, tokens: dict[str, str], dry_run: bool) -> list[Path]:
    generated: list[Path] = []
    for item in source.rglob('*'):
        if item.is_dir(): continue
        relative = Path(str(item.relative_to(source)).replace('__MODULE__', tokens['MODULE']).replace('__FEATURE__', tokens['FEATURE']))
        output = target / relative
        content = item.read_text(encoding='utf-8')
        for key, value in tokens.items(): content = content.replace(f'__{key}__', value)
        if '__' in content: raise RuntimeError(f'Unresolved template token in {item}')
        generated.append(output)
        if not dry_run:
            output.parent.mkdir(parents=True, exist_ok=True)
            if output.exists(): raise FileExistsError(f'Refusing to overwrite {output}')
            output.write_text(content, encoding='utf-8')
    return generated

def main() -> int:
    parser=argparse.ArgumentParser(description='Generate a K-ArtSell Vertical Slice backend/frontend packet.')
    parser.add_argument('--module', required=True, type=valid_identifier)
    parser.add_argument('--feature', required=True, type=valid_identifier)
    parser.add_argument('--slice-id', required=True, help='e.g. VS-14')
    parser.add_argument('--root', type=Path, default=Path.cwd())
    parser.add_argument('--dry-run', action='store_true')
    args=parser.parse_args()
    template_root=Path(__file__).resolve().parents[1] / 'templates' / 'vertical-slice'
    tokens={'MODULE':args.module,'FEATURE':args.feature,'SLICE_ID':args.slice_id}
    targets=[(template_root/'backend',args.root/'src'/f'KArtSell.Modules.{args.module}'/'Features'/args.feature),(template_root/'frontend',args.root/'frontend'/'src'/'features'/re.sub(r'(?<!^)(?=[A-Z])','-',args.feature).lower())]
    generated=[]
    for source,target in targets: generated.extend(render_tree(source,target,tokens,args.dry_run))
    for path in generated: print(path)
    return 0
if __name__=='__main__': raise SystemExit(main())
