[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "plugin.video.jacktook"
version = "1.15.0"
description = "Kodi addon for searching and streaming torrents via debrid services"
requires-python = ">=3.7"

# ──────────────────────────────────────────────
# Ruff — linter + formatter
# ──────────────────────────────────────────────

[tool.ruff]
# Target Python 3.7+ for Kodi compatibility (the addon has a py37 compat checker)
target-version = "py37"
line-length = 100
indent-width = 4

# Files/directories to exclude
exclude = [
    ".git",
    ".venv",
    ".agent",
    ".agents",
    ".opencode",
    ".worktrees",
    ".mypy_cache",
    ".pytest_cache",
    "docs",
    "scripts",
    "tests/manual_*.py",
    "__pycache__",
    "*.pyc",
]

# ── Formatter ─────────────────────────────────
[tool.ruff.format]
# Use Black-compatible formatting
quote-style = "double"
indent-style = "space"
line-ending = "auto"
skip-magic-trailing-comma = false

# ── Linter ────────────────────────────────────
[tool.ruff.lint]
# Start with a pragmatic set of rules — expand as needed
select = [
    "E",    # pycodestyle errors
    "W",    # pycodestyle warnings
    "F",    # Pyflakes (logic errors)
    "I",    # isort (import ordering)
    "N",    # pep8-naming
    "UP",   # pyupgrade (only safe auto-fixes for target version)
    "B",    # flake8-bugbear (likely bugs)
    "SIM",  # flake8-simplify (simplifications)
    "D",    # pydocstyle (docstring conventions)
    "YTT",  # flake8-2020 (version check idioms)
    "RUF",  # Ruff-specific rules
]

# Ignore rules that are too noisy for this codebase
ignore = [
    "D100",   # Missing docstring in public module
    "D101",   # Missing docstring in public class
    "D102",   # Missing docstring in public method
    "D103",   # Missing docstring in public function
    "D104",   # Missing docstring in public package
    "D105",   # Missing docstring in magic method
    "D107",   # Missing docstring in __init__
    "D200",   # One-line docstring should fit on one line
    "D203",   # 1 blank line required before class docstring
    "D212",   # Multi-line docstring summary should start at first line
    "D213",   # Multi-line docstring summary should start at second line
    "D401",   # First line should be in imperative mood
    "D402",   # First line should not be function's signature
    "D413",   # Blank line after last section
    "D414",   # Section has no content
    "D415",   # First line should end with period
    "D416",   # Section name should end with colon
    "D417",   # Missing argument descriptions
    "N802",   # Function name should be lowercase (allow camelCase for Kodi compat)
    "N803",   # Argument name should be lowercase
    "N806",   # Variable in function should be lowercase
    "N815",   # Variable in class scope should not be mixedCase
    "SIM108", # Use ternary operator (if-else blocks)
    "SIM115", # Use context handler for opening files
    "SIM117", # Merge with-statements
    "UP007",  # Use X | Y for type unions (not compatible with py37)
    "UP006",  # Use X instead of typing.X
    "UP035",  # Import from typing deprecated
    "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
]

# ── isort settings ────────────────────────────
[tool.ruff.lint.isort]
known-first-party = ["lib"]
known-third-party = ["xbmc", "xbmcgui", "xbmcplugin", "xbmcaddon", "xbmcvfs"]
force-single-line = false
order-by-type = true

# ── pydocstyle ────────────────────────────────
[tool.ruff.lint.pydocstyle]
convention = "google"

# ── pycodestyle ───────────────────────────────
[tool.ruff.lint.pycodestyle]
max-doc-length = 100

# ── Per-file-rule overrides ───────────────────
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["D", "N", "SIM", "E402", "E501"]
"scripts/**" = ["D", "N", "SIM", "UP"]
# Vendor code: ignore everything except critical bugs (F, B)
"lib/vendor/**" = ["ALL"]
"lib/api/tmdbv3api/**" = ["ALL"]
"lib/utils/parsers/xmltodict.py" = ["ALL"]

# ──────────────────────────────────────────────
# mypy — static type checker
# ──────────────────────────────────────────────

[tool.mypy]
python_version = "3.13"
strict_optional = true
warn_unused_ignores = true
warn_redundant_casts = true
warn_return_any = true
no_implicit_optional = true
show_error_codes = true
ignore_missing_imports = true

# Exclude test/script/doc directories from initial file discovery
exclude = [
    "tests/",
    "scripts/",
    "docs/",
]

# ──────────────────────────────────────────────
# pytest — test runner
# ──────────────────────────────────────────────

# Per-module overrides: skip vendored third-party code
[[tool.mypy.overrides]]
module = "lib.vendor.*"
follow_imports = "skip"
ignore_errors = true

[[tool.mypy.overrides]]
module = "lib.utils.parsers.xmltodict"
follow_imports = "skip"
ignore_errors = true

[[tool.mypy.overrides]]
module = "lib.api.tmdbv3api.*"
follow_imports = "skip"
ignore_errors = true

[tool.pytest.ini_options]
minversion = "7.0"
addopts = [
    "-q",
    "--tb=short",
]
testpaths = ["tests"]
python_files = ["test_*.py", "verify_*.py"]
filterwarnings = [
    "ignore::DeprecationWarning:lib.db.cached:413",
]

# ──────────────────────────────────────────────
# Coverage — pytest-cov
# ──────────────────────────────────────────────

[tool.coverage.run]
source = ["lib"]
omit = [
    "tests/*",
    "scripts/*",
    "*/__pycache__/*",
]

[tool.coverage.report]
show_missing = true
skip_covered = true
skip_empty = true
fail_under = 0
