import unittest
import shutil
import os
import tempfile
from pathlib import Path
from ontoenv import OntoEnv


class TestOntoEnvInit(unittest.TestCase):
    def tearDown(self):
        # Clean up any accidental .ontoenv in cwd
        if Path(".ontoenv").exists():
            shutil.rmtree(".ontoenv")

    def test_init_recreate_new_dir(self):
        with tempfile.TemporaryDirectory() as td:
            root = Path(td)
            env_path = root / "new_env"
            self.assertFalse(env_path.exists())
            env = OntoEnv(path=env_path, recreate=True)
            self.assertTrue((env_path / ".ontoenv").is_dir())
            sp = env.store_path()
            self.assertIsNotNone(sp)
            self.assertTrue(Path(sp).is_dir())

    def test_init_recreate_existing_empty_dir(self):
        with tempfile.TemporaryDirectory() as td:
            env_path = Path(td) / "empty_env"
            env_path.mkdir()
            self.assertTrue(env_path.is_dir())
            env = OntoEnv(path=env_path, recreate=True)
            self.assertTrue((env_path / ".ontoenv").is_dir())
            self.assertIsNotNone(env.store_path())

    def test_init_load_from_existing_dir(self):
        with tempfile.TemporaryDirectory() as td:
            env_path = Path(td) / "existing_env"
            env_path.mkdir()
            env = OntoEnv(path=env_path, recreate=True)
            env.flush()
            del env
            # load existing
            env2 = OntoEnv(path=env_path, read_only=False)
            self.assertEqual(env2.store_path(), str(env_path / ".ontoenv"))

    def test_init_recreate_existing_dir(self):
        with tempfile.TemporaryDirectory() as td:
            env_path = Path(td) / "existing_env"
            env_path.mkdir()
            env = OntoEnv(path=env_path, recreate=True)
            (env_path / ".ontoenv" / "dummy.txt").touch()
            self.assertTrue((env_path / ".ontoenv" / "dummy.txt").exists())
            # Recreate
            env = OntoEnv(path=env_path, recreate=True)
            self.assertTrue((env_path / ".ontoenv").is_dir())
            self.assertFalse((env_path / ".ontoenv" / "dummy.txt").exists())
            self.assertEqual(len(env.get_ontology_names()), 0)

    def test_init_read_only(self):
        with tempfile.TemporaryDirectory() as td:
            env_path = Path(td) / "existing_env"
            dummy_file = Path(td) / "dummy.ttl"
            env_path.mkdir()
            dummy_file.write_text(
                "@prefix owl: <http://www.w3.org/2002/07/owl#> .\n<urn:dummy> a owl:Ontology .\n",
                encoding="utf-8",
            )
            env1 = OntoEnv(path=env_path, recreate=True)
            env1.close()
            env = OntoEnv(path=env_path, read_only=True)
            self.assertTrue((env_path / ".ontoenv").is_dir())
            with self.assertRaisesRegex(ValueError, "Cannot add to read-only store"):
                env.add(dummy_file.resolve().as_uri())

    def test_init_no_config_requires_existing(self):
        original_cwd = Path.cwd()
        with tempfile.TemporaryDirectory() as td:
            os.chdir(td)
            try:
                with self.assertRaises(FileNotFoundError):
                    OntoEnv()
            finally:
                os.chdir(original_cwd)

    def test_init_no_config_create_flag(self):
        original_cwd = Path.cwd()
        with tempfile.TemporaryDirectory() as td:
            os.chdir(td)
            try:
                env = OntoEnv(create_or_use_cached=True)
                self.assertTrue(Path(".ontoenv").is_dir())
                env.close()
            finally:
                os.chdir(original_cwd)

    def test_init_path_auto_initializes(self):
        with tempfile.TemporaryDirectory() as td:
            env_path = Path(td) / "no_env_here"
            env_path.mkdir()
            env = OntoEnv(path=env_path, create_or_use_cached=True)
            self.assertTrue((env_path / ".ontoenv").is_dir())
            env.close()

    def test_init_temporary(self):
        with tempfile.TemporaryDirectory() as td:
            env_path = Path(td) / "temp_env_root"
            env = OntoEnv(temporary=True, root=str(env_path), strict=False)
            self.assertFalse((env_path / ".ontoenv").exists())
            self.assertIsNone(env.store_path())
            try:
                env.add("http://example.com/nonexistent.ttl")
            except ValueError as e:
                self.assertNotIn("Cannot add to read-only store", str(e))
            except Exception:
                pass


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