from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_PATH = ROOT / "plugins" / "1c" / "metadata" / "examples" / "metadata.example.json"
VALID_KINDS = {
    "catalog",
    "document",
    "register",
    "common_module",
    "enum",
    "report",
    "processing",
    "other",
}


def validate_snapshot(data: object, path: Path) -> list[str]:
    errors: list[str] = []
    if not isinstance(data, dict):
        return [f"{path}: snapshot must be a JSON object"]

    if data.get("schema_version") not in {1, 2}:
        errors.append(f"{path}: schema_version must be 1 or 2")

    source = data.get("source")
    if not isinstance(source, dict) or not source.get("name"):
        errors.append(f"{path}: source.name is required")

    if not data.get("created_at"):
        errors.append(f"{path}: created_at is required")

    objects = data.get("objects")
    if not isinstance(objects, list):
        errors.append(f"{path}: objects must be a list")
        return errors

    for index, obj in enumerate(objects):
        prefix = f"{path}: objects[{index}]"
        if not isinstance(obj, dict):
            errors.append(f"{prefix} must be an object")
            continue
        kind = obj.get("kind")
        name = obj.get("name")
        if kind not in VALID_KINDS:
            errors.append(f"{prefix}.kind must be one of {sorted(VALID_KINDS)}")
        if not name:
            errors.append(f"{prefix}.name is required")

        for attr_index, attr in enumerate(obj.get("attributes") or []):
            if not isinstance(attr, dict) or not attr.get("name"):
                errors.append(f"{prefix}.attributes[{attr_index}].name is required")

        for section_index, section in enumerate(obj.get("tabular_sections") or []):
            section_prefix = f"{prefix}.tabular_sections[{section_index}]"
            if not isinstance(section, dict) or not section.get("name"):
                errors.append(f"{section_prefix}.name is required")
                continue
            for attr_index, attr in enumerate(section.get("attributes") or []):
                if not isinstance(attr, dict) or not attr.get("name"):
                    errors.append(f"{section_prefix}.attributes[{attr_index}].name is required")

        if data.get("schema_version") == 2:
            for module_index, module in enumerate(obj.get("modules") or []):
                if not isinstance(module, dict) or not module.get("module_id"):
                    errors.append(f"{prefix}.modules[{module_index}].module_id is required")

    return errors


def main() -> int:
    parser = argparse.ArgumentParser(description="Validate a 1C metadata snapshot.")
    parser.add_argument("path", nargs="?", type=Path, default=DEFAULT_PATH)
    args = parser.parse_args()

    with args.path.open("r", encoding="utf-8") as handle:
        data = json.load(handle)

    errors = validate_snapshot(data, args.path)
    if errors:
        print("1C metadata snapshot validation failed:", file=sys.stderr)
        for error in errors:
            print(f"- {error}", file=sys.stderr)
        return 1

    print(f"Validated 1C metadata snapshot: {args.path}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
