# Generate reproducible furnished Minecraft Java 1.21.1 lodges from a constrained grammar.
from __future__ import annotations

import argparse
import json
from pathlib import Path

from blocks import Build as BlockBuild, CONFIG, blockstates_equivalent
from lodge.plan import DEFAULT_SEED, DOMAINS, LIMITS, Plan, resolve
from lodge.geometry import Scene


class Build(BlockBuild):
    """Compile a resolved architectural plan using the toolset export contract."""

    def __init__(self, seed: int = DEFAULT_SEED, parameters: dict | None = None, limits: dict | None = None):
        self.plan = resolve(seed, parameters, limits)
        super().__init__(self.plan.size_xyz, seed)
        self.scene = None

    def build(self):
        self.scene = Scene(self.plan).build()
        ox, oy, oz = self.plan.origin
        materials = {}
        for (x, y, z), state in sorted(self.scene.blocks.items()):
            if state not in materials:
                materials[state] = self.material(state)
            self.put(x + ox, y + oy, z + oz, materials[state])
        return self

    def export(self, path: Path):
        super().export(path)
        record = self.plan.record()
        record['rooms'] = self.scene.rooms
        record['structural_signature'] = self.plan.signature()
        from lodge.validation import geometry_signature
        record['placed_geometry_signature'] = geometry_signature(self.scene)
        path.with_suffix('.json').write_text(json.dumps(record, indent=2) + '\n')
        return path


def generate(seed: int = DEFAULT_SEED, parameters: dict | None = None, output: Path | None = None, validate: bool = True, limits: dict | None = None) -> Build:
    """Compile, validate, and optionally export one reproducible architectural sample.

    Args:
        seed (int): Signed 64-bit seed, default 20260924.
        parameters (dict): Explicit architectural constraints from DOMAINS.
        output (Path): Optional schematic path, with adjacent resolved JSON.
        validate (bool): Run geometry checks before export.
        limits (dict): Optional documented resource limits.

    Returns:
        Build: Blocks, resolved plan, and verification evidence.
    """
    build = Build(seed, parameters, limits).build()
    if validate:
        from lodge.validation import validate_scene
        build.validation = validate_scene(build.scene)
    if output is not None:
        build.export(Path(output))
        build.verify(Path(output))
    return build


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--seed', type=int, default=DEFAULT_SEED)
    parser.add_argument('--output', type=Path, default=Path('output.litematic'))
    parser.add_argument('--config', type=Path, help='JSON architectural parameter overrides')
    parser.add_argument('--set', action='append', default=[], metavar='KEY=JSON', help='Override a parameter, e.g. --set floors=2 --set topology=ell')
    args = parser.parse_args()
    params = json.loads(args.config.read_text()) if args.config else {}
    for setting in args.set:
        key, value = setting.split('=', 1)
        try:
            params[key] = json.loads(value)
        except json.JSONDecodeError:
            params[key] = value
    try:
        build = generate(args.seed, params, args.output)
    except ValueError as error:
        parser.error(str(error))
    print(json.dumps({'output': str(args.output), 'seed': args.seed, 'bounds': build.plan.size_xyz, 'validation': build.validation}, indent=2))


if __name__ == '__main__':
    main()
