import tempfile
import unittest
from pathlib import Path
from unittest import mock

import gnos.chunking.registry as reg
from examples.gnos_example_chunker.chunker import ExampleFormatAwareIdentityV1

from gnos.core.add import add_path
from gnos.core.store import ObjectStore
from gnos.manifest.codec import load_manifest_bytes


class _FakeDist:
    def __init__(self, name: str) -> None:
        self.name = name


class _FakeEntryPoint:
    def __init__(self, obj, dist_name: str) -> None:
        self._obj = obj
        self.dist = _FakeDist(dist_name)

    def load(self):
        return self._obj


class TestExamplePluginChunker(unittest.TestCase):
    def test_example_chunker_persists_effective_params(self) -> None:
        # Reset registry state to avoid coupling to other tests.
        reg._PLUGINS_LOADED = False
        reg._CHUNKERS = dict(reg._BUILTIN_CHUNKERS)
        reg._SOURCES = {name: "core" for name in reg._BUILTIN_CHUNKERS}

        plugin = ExampleFormatAwareIdentityV1()
        with mock.patch("gnos.chunking.registry._iter_entry_points", return_value=[_FakeEntryPoint(plugin, "example")]):
            with tempfile.TemporaryDirectory() as tmp:
                root = Path(tmp)
                store = ObjectStore(root / ".gnos")
                store.init()
                path = root / "README.md"
                path.write_text("# hi\n", encoding="utf-8")

                batch = add_path(path, store, format="markdown", chunking=plugin.name)
                self.assertEqual(len(batch.results), 1)
                manifest_hash = batch.results[0].manifest_hash

                manifest_bytes = store.get(manifest_hash)
                self.assertIsNotNone(manifest_bytes)
                manifest = load_manifest_bytes(manifest_bytes)  # type: ignore[arg-type]

                self.assertEqual(manifest.chunking["method"], plugin.name)
                # The chunker defaulted parser based on ctx.format and persisted it.
                self.assertEqual(manifest.chunking["params"]["format"], "markdown")
                self.assertEqual(manifest.chunking["params"]["parser"], "commonmark-0.30")


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

