"""
Behavioral tests for json_loader module.

Tests the SimpleJSONLoader and extract_strings_from_json function.
"""

import json
import tempfile
from pathlib import Path


class TestExtractStringsFromJson:
    """Tests for extract_strings_from_json function."""

    def test_extracts_simple_string(self):
        """Extracts simple string value."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = "hello world"
        result = extract_strings_from_json(data)
        assert len(result) == 1
        assert result[0][1] == "hello world"

    def test_extracts_string_from_dict(self):
        """Extracts string values from dict."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"name": "John", "city": "NYC"}
        result = extract_strings_from_json(data)
        assert len(result) == 2
        values = [r[1] for r in result]
        assert "John" in values
        assert "NYC" in values

    def test_includes_path_for_dict_values(self):
        """Includes JSON path for dict values."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"name": "John"}
        result = extract_strings_from_json(data)
        assert result[0][0] == "name"
        assert result[0][1] == "John"

    def test_extracts_strings_from_list(self):
        """Extracts strings from list."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = ["apple", "banana", "cherry"]
        result = extract_strings_from_json(data)
        assert len(result) == 3
        values = [r[1] for r in result]
        assert "apple" in values
        assert "banana" in values
        assert "cherry" in values

    def test_includes_index_in_path_for_list(self):
        """Includes index in path for list items."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = ["first", "second"]
        result = extract_strings_from_json(data)
        assert "[0]" in result[0][0]
        assert "[1]" in result[1][0]

    def test_handles_nested_dict(self):
        """Handles nested dictionaries."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"user": {"name": "John", "address": {"city": "NYC"}}}
        result = extract_strings_from_json(data)
        paths = [r[0] for r in result]
        assert "user.name" in paths
        assert "user.address.city" in paths

    def test_handles_dict_with_list(self):
        """Handles dict containing list."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"items": ["a", "b", "c"]}
        result = extract_strings_from_json(data)
        assert len(result) == 3
        paths = [r[0] for r in result]
        assert "items[0]" in paths

    def test_skips_numbers(self):
        """Skips numeric values."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"name": "John", "age": 30}
        result = extract_strings_from_json(data)
        assert len(result) == 1
        assert result[0][1] == "John"

    def test_skips_booleans(self):
        """Skips boolean values."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"name": "John", "active": True}
        result = extract_strings_from_json(data)
        assert len(result) == 1
        assert result[0][1] == "John"

    def test_skips_null(self):
        """Skips null values."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"name": "John", "email": None}
        result = extract_strings_from_json(data)
        assert len(result) == 1

    def test_returns_empty_for_empty_dict(self):
        """Returns empty list for empty dict."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {}
        result = extract_strings_from_json(data)
        assert result == []

    def test_returns_empty_for_empty_list(self):
        """Returns empty list for empty list."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = []
        result = extract_strings_from_json(data)
        assert result == []

    def test_handles_deeply_nested_structure(self):
        """Handles deeply nested structure."""
        from local_deep_research.document_loaders.json_loader import (
            extract_strings_from_json,
        )

        data = {"a": {"b": {"c": {"d": {"e": "value"}}}}}
        result = extract_strings_from_json(data)
        assert len(result) == 1
        assert result[0][0] == "a.b.c.d.e"
        assert result[0][1] == "value"


class TestSimpleJSONLoaderInit:
    """Tests for SimpleJSONLoader initialization."""

    def test_accepts_string_path(self):
        """Accepts string path."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        loader = SimpleJSONLoader("/path/to/file.json")
        assert loader.file_path == Path("/path/to/file.json")

    def test_accepts_path_object(self):
        """Accepts Path object."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        loader = SimpleJSONLoader(Path("/path/to/file.json"))
        assert loader.file_path == Path("/path/to/file.json")

    def test_default_encoding_is_utf8(self):
        """Default encoding is utf-8."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        loader = SimpleJSONLoader("/path/to/file.json")
        assert loader.encoding == "utf-8"

    def test_accepts_custom_encoding(self):
        """Accepts custom encoding."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        loader = SimpleJSONLoader("/path/to/file.json", encoding="latin-1")
        assert loader.encoding == "latin-1"

    def test_default_include_paths_is_true(self):
        """Default include_paths is True."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        loader = SimpleJSONLoader("/path/to/file.json")
        assert loader.include_paths is True

    def test_accepts_include_paths_false(self):
        """Accepts include_paths=False."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        loader = SimpleJSONLoader("/path/to/file.json", include_paths=False)
        assert loader.include_paths is False


class TestSimpleJSONLoaderLoad:
    """Tests for SimpleJSONLoader load functionality."""

    def test_loads_valid_json(self):
        """Loads valid JSON file."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump({"name": "Test", "value": "Data"}, f)
            f.flush()
            path = f.name

        try:
            loader = SimpleJSONLoader(path)
            docs = loader.load()
            assert len(docs) == 1
            assert "name: Test" in docs[0].page_content
            assert "value: Data" in docs[0].page_content
        finally:
            Path(path).unlink()

    def test_includes_source_in_metadata(self):
        """Includes source path in metadata."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump({"key": "value"}, f)
            f.flush()
            path = f.name

        try:
            loader = SimpleJSONLoader(path)
            docs = loader.load()
            assert "source" in docs[0].metadata
            assert path in docs[0].metadata["source"]
        finally:
            Path(path).unlink()

    def test_includes_file_type_in_metadata(self):
        """Includes file_type in metadata."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump({"key": "value"}, f)
            f.flush()
            path = f.name

        try:
            loader = SimpleJSONLoader(path)
            docs = loader.load()
            assert docs[0].metadata.get("file_type") == "json"
        finally:
            Path(path).unlink()

    def test_includes_string_count_in_metadata(self):
        """Includes string_count in metadata."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump({"a": "1", "b": "2", "c": "3"}, f)
            f.flush()
            path = f.name

        try:
            loader = SimpleJSONLoader(path)
            docs = loader.load()
            assert docs[0].metadata.get("string_count") == 3
        finally:
            Path(path).unlink()

    def test_handles_invalid_json(self):
        """Handles invalid JSON gracefully."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            f.write("{ invalid json }")
            f.flush()
            path = f.name

        try:
            loader = SimpleJSONLoader(path)
            docs = loader.load()
            assert len(docs) == 1
            assert docs[0].metadata.get("parse_error") is True
        finally:
            Path(path).unlink()

    def test_loads_without_paths(self):
        """Loads without including paths when include_paths=False."""
        from local_deep_research.document_loaders.json_loader import (
            SimpleJSONLoader,
        )

        with tempfile.NamedTemporaryFile(
            mode="w", suffix=".json", delete=False
        ) as f:
            json.dump({"name": "TestValue"}, f)
            f.flush()
            path = f.name

        try:
            loader = SimpleJSONLoader(path, include_paths=False)
            docs = loader.load()
            # Should just have the value, not "name: TestValue"
            assert "TestValue" in docs[0].page_content
            # The colon indicates path was included
            assert "name:" not in docs[0].page_content
        finally:
            Path(path).unlink()


class TestExtractTextFromJson:
    """Tests for extract_text_from_json function."""

    def test_extracts_text_from_bytes(self):
        """Extracts text from bytes content."""
        from local_deep_research.document_loaders.json_loader import (
            extract_text_from_json,
        )

        content = b'{"name": "John", "city": "NYC"}'
        result = extract_text_from_json(content)
        assert "name: John" in result
        assert "city: NYC" in result

    def test_handles_unicode(self):
        """Handles Unicode content."""
        from local_deep_research.document_loaders.json_loader import (
            extract_text_from_json,
        )

        content = '{"greeting": "你好"}'.encode("utf-8")
        result = extract_text_from_json(content)
        assert "你好" in result

    def test_handles_invalid_json_bytes(self):
        """Returns raw text for invalid JSON."""
        from local_deep_research.document_loaders.json_loader import (
            extract_text_from_json,
        )

        content = b"{ not valid json }"
        result = extract_text_from_json(content)
        assert "not valid json" in result

    def test_uses_custom_encoding(self):
        """Uses custom encoding when specified."""
        from local_deep_research.document_loaders.json_loader import (
            extract_text_from_json,
        )

        # Latin-1 encoded content
        content = '{"text": "café"}'.encode("latin-1")
        result = extract_text_from_json(content, encoding="latin-1")
        assert "café" in result
