import json
import tempfile
import unittest
from pathlib import Path

from gnos.core.attest import AttestationError, attest_manifest_bytes, attest_doc_id
from gnos.core.hash import sha256_hex
from gnos.core.store import ObjectStore
from gnos.index.local import LocalIndex
from gnos.manifest.codec import dump_manifest_bytes
from gnos.manifest.schema import DocManifest


class TestAttestMoreErrors(unittest.TestCase):
    def test_attest_manifest_unknown_chunker(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            store = ObjectStore(Path(tmp))
            store.init()
            chunk = b"x"
            h = sha256_hex(chunk)
            store.put(h, chunk)
            manifest = DocManifest(
                type="doc-manifest",
                version=1,
                doc_id=sha256_hex(chunk),
                format="text",
                chunking={"method": "unknown-v1", "params": {}},
                chunks=[{"hash": h}],
            )
            manifest_bytes = dump_manifest_bytes(manifest)
            with self.assertRaises(AttestationError):
                attest_manifest_bytes(manifest_bytes, store)

    def test_attest_manifest_reconstruct_mismatch(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            store = ObjectStore(Path(tmp))
            store.init()
            chunk = b"x"
            h = sha256_hex(chunk)
            store.put(h, chunk)
            manifest = DocManifest(
                type="doc-manifest",
                version=1,
                doc_id="0" * 64,
                format="text",
                chunking={"method": "sequential-v1", "params": {"chunk_size": 1024}},
                chunks=[{"hash": h}],
            )
            manifest_bytes = dump_manifest_bytes(manifest)
            with self.assertRaises(AttestationError):
                attest_manifest_bytes(manifest_bytes, store)

    def test_attest_doc_no_manifests(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            store = ObjectStore(root / ".gnos")
            store.init()
            index = LocalIndex(root / ".gnos" / "index.json")
            index.path.write_text(json.dumps({"documents": {"d" * 64: {"manifests": []}}}), encoding="utf-8")
            with self.assertRaises(AttestationError):
                attest_doc_id("d" * 64, store, index)

    def test_attest_doc_manifest_missing_in_store(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            store = ObjectStore(root / ".gnos")
            store.init()
            index = LocalIndex(root / ".gnos" / "index.json")
            index.path.write_text(
                json.dumps({"documents": {"d" * 64: {"manifests": ["m" * 64]}}}),
                encoding="utf-8",
            )
            with self.assertRaises(AttestationError):
                attest_doc_id("d" * 64, store, index)


if __name__ == "__main__":
    unittest.main()

