import tempfile
import unittest
from pathlib import Path

from gnos.core.add import add_path, AddError
from gnos.core.hash import sha256_hex, canonicalize_bytes
from gnos.core.store import ObjectStore
from gnos.manifest.codec import load_manifest_bytes


class TestAdd(unittest.TestCase):
    def test_add_requires_init(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            store = ObjectStore(Path(tmp) / ".gnos")
            path = Path(tmp) / "README.md"
            path.write_text("# Title\n\nBody\n", encoding="utf-8")
            with self.assertRaises(AddError):
                add_path(path, store)

    def test_add_stores_manifest_and_chunks(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            store = ObjectStore(root / ".gnos")
            store.init()

            path = root / "README.md"
            path.write_text("# Title\n\nBody\n", encoding="utf-8")

            batch = add_path(path, store)
            result = batch.results[0]
            self.assertTrue(store.has(result.manifest_hash))

            manifest_bytes = store.get(result.manifest_hash)
            self.assertIsNotNone(manifest_bytes)

            manifest = load_manifest_bytes(manifest_bytes)
            self.assertEqual(manifest.doc_id, result.doc_id)
            self.assertEqual(len(manifest.chunks), result.chunk_count)

            # Verify that chunks are present and hashes are correct.
            for ch in manifest.chunks:
                data = store.get(ch["hash"])
                self.assertIsNotNone(data)
                self.assertEqual(sha256_hex(data), ch["hash"])

            # Verify doc_id matches canonical bytes.
            raw = path.read_bytes()
            canon = canonicalize_bytes(raw)
            self.assertEqual(sha256_hex(canon), result.doc_id)


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