"""
Knowledge loader for the markitect helper.

Reads markitect's own documentation files and returns them as a
concatenated string for use as LLM context.
"""

import importlib
from pathlib import Path
from typing import List


# Docs to load relative to the project root, in priority order.
_DOC_PATHS: List[str] = [
    "INTRODUCTION.md",
    "docs/CLI_TUTORIAL.md",
    "docs/PROJECT_STRUCTURE.md",
    "docs/SCHEMA_MANAGEMENT_GUIDE.md",
    "docs/PLUGIN_SYSTEM.md",
    "docs/ERROR_HANDLING_STRATEGY.md",
    "docs/architecture/CAPABILITIES_ARCHITECTURE.md",
    "docs/architecture/caching-system.md",
    "docs/ASSET_MANAGEMENT_USER_GUIDE.md",
    "docs/graphql_interface.md",
    "examples/content-generator/TUTORIAL.md",
    "examples/infospace-with-history/TUTORIAL.md",
]

# Glob patterns (relative to project root) for additional docs.
_DOC_GLOBS: List[str] = [
    "docs/user-guides/*.md",
]

# Modules whose docstrings to include.
_MODULE_DOCSTRINGS: List[str] = [
    "markitect.prompts",
    "markitect.llm",
]


def _find_project_root() -> Path:
    """Return the markitect project root directory.

    Walks up from this file (markitect/helper/knowledge.py) to find the
    directory that contains ``markitect/`` as a package *and* has a
    ``pyproject.toml`` or ``INTRODUCTION.md``.
    """
    candidate = Path(__file__).resolve().parent.parent.parent
    # Verify we landed in the right place.
    if (candidate / "pyproject.toml").exists() or (candidate / "INTRODUCTION.md").exists():
        return candidate
    # Fallback: try CWD.
    cwd = Path.cwd()
    if (cwd / "markitect").is_dir():
        return cwd
    return candidate


def collect_knowledge() -> str:
    """Load markitect documentation and return as a single string.

    Reads documentation files from the project root, concatenates them
    with section headers, and appends relevant module docstrings.
    Missing files are silently skipped.
    """
    root = _find_project_root()
    sections: List[str] = []

    # Fixed-path documents.
    for rel_path in _DOC_PATHS:
        filepath = root / rel_path
        if filepath.is_file():
            try:
                content = filepath.read_text(encoding="utf-8")
                sections.append(f"## {rel_path}\n\n{content}")
            except OSError:
                continue

    # Glob-pattern documents.
    for pattern in _DOC_GLOBS:
        for filepath in sorted(root.glob(pattern)):
            if filepath.is_file():
                rel = filepath.relative_to(root)
                try:
                    content = filepath.read_text(encoding="utf-8")
                    sections.append(f"## {rel}\n\n{content}")
                except OSError:
                    continue

    # Module docstrings.
    for mod_name in _MODULE_DOCSTRINGS:
        try:
            mod = importlib.import_module(mod_name)
            if mod.__doc__:
                sections.append(f"## Module: {mod_name}\n\n{mod.__doc__.strip()}")
        except ImportError:
            continue

    return "\n\n---\n\n".join(sections)
