import tempfile
import unittest
from pathlib import Path
from unittest import mock
import gnos.chunking.registry as reg
from examples.gnos_example_derived_chunker.chunker import ExampleDerivedChunker

from gnos.core.add import add_path, AddError
from gnos.core.store import ObjectStore
from gnos.chunking.api import Chunker, ChunkerContext, ManifestChunk, SplitChunk, SplitResult


class TestAddRoundtrip(unittest.TestCase):
    def test_add_fails_on_bad_reconstruct(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            store = ObjectStore(root / ".gnos")
            store.init()
            path = root / "a.txt"
            path.write_text("hello\n", encoding="utf-8")

            class _BadChunker(Chunker):
                name = "bad-v1"

                def split(self, data: bytes, params, _ctx: ChunkerContext):
                    return SplitResult(chunks=[SplitChunk(data=data)], params=params)

                def reconstruct(self, _chunks: list[ManifestChunk], _params):
                    return b"bad"

            bad_method = _BadChunker()

            with mock.patch("gnos.core.add.get_method", return_value=bad_method):
                with self.assertRaises(AddError):
                    add_path(path, store, format="text", chunking="bad-v1")

    def test_add_fails_with_example_derived_chunker(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            root = Path(tmp)
            store = ObjectStore(root / ".gnos")
            store.init()
            path = root / "a.txt"
            path.write_text("hello\n", encoding="utf-8")

            reg._CHUNKERS["example-derived-v1"] = ExampleDerivedChunker()
            reg._SOURCES["example-derived-v1"] = "example"
            try:
                with self.assertRaises(AddError):
                    add_path(path, store, format="text", chunking="example-derived-v1")
            finally:
                reg._CHUNKERS.pop("example-derived-v1", None)
                reg._SOURCES.pop("example-derived-v1", None)


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