# Ruff configuration for catching duplicate imports and other issues
# Ruff is faster and more comprehensive than flake8

# Same line length as Black
line-length = 88

# Target Python 3.8+
target-version = "py38"

# Enable specific rule categories
[lint]
select = [
    "F",     # Pyflakes (includes duplicate import detection)
    "E",     # pycodestyle errors
    "W",     # pycodestyle warnings
    "I",     # isort (import sorting)
    "N",     # pep8-naming
    "UP",    # pyupgrade
    "B",     # flake8-bugbear (catches common bugs)
    "C4",    # flake8-comprehensions
    "DTZ",   # flake8-datetimez
    "ISC",   # flake8-implicit-str-concat
    "PIE",   # flake8-pie
    "RET",   # flake8-return
    "SIM",   # flake8-simplify
    "TCH",   # flake8-type-checking (imports in TYPE_CHECKING blocks)
    "PTH",   # flake8-use-pathlib
    "PL",    # Pylint rules
    "RUF",   # Ruff-specific rules
]

# Specific rules to catch duplicate imports and scope issues
extend-select = [
    "F401",  # Unused imports
    "F402",  # Import shadowed by loop variable
    "F403",  # Star imports
    "F404",  # Late future import
    "F405",  # Star import undefined names
    "F811",  # Redefinition of unused variable (catches duplicate imports!)
    "F821",  # Undefined name (catches scope issues!)
    "F822",  # Undefined name in __all__
    "F823",  # Local variable referenced before assignment
    "F841",  # Local variable assigned but never used
    "E902",  # IOError (can catch import errors)
]

# Rules to ignore
ignore = [
    "E203",  # Whitespace before ':' (Black compatibility)
    "E501",  # Line too long (handled by formatter)
    "E721",  # Type comparison using type() instead of isinstance()
    "E741",  # Ambiguous variable name - too many to fix now
    "E402",  # Module level import not at top of file (common pattern in this codebase)
    "B007",  # Loop control variable not used - intentional in some cases
    "B008",  # Do not perform function calls in argument defaults
    "B012",  # return/continue/break inside finally - intentional in some cases
    "B017",  # assertRaises(Exception) - too broad exception check
    "B018",  # Useless expression - false positives in some cases
    "B019",  # Use of lru_cache on methods - intentional caching pattern
    "B023",  # Function definition does not bind loop variable - false positives
    "B024",  # Abstract base class without abstract methods - intentional
    "B034",  # re.sub/subn replacement is empty string - false positives
    "B905",  # zip() without explicit strict= parameter
    "C901",  # Too complex (can enable later)
    "DTZ001", # datetime without timezone - too many to fix now
    "DTZ006", # datetime without timezone - too many to fix now
    "DTZ007", # datetime without timezone - too many to fix now
    "F402",  # Import shadowed by loop variable - false positives
    "F403",  # Star imports - allowed in specific contexts
    "F811",  # Redefinition of unused variable - intentional in some cases
    "F823",  # Local variable referenced before assignment - false positives
    "N801",  # Class name should use CapWords - legacy compatibility
    "N802",  # Function name should be lowercase - legacy compatibility
    "N803",  # Argument name should be lowercase - legacy compatibility
    "N806",  # Variable in function should be lowercase - legacy compatibility
    "N807",  # Function name should not start with lowercase - legacy compatibility
    "N812",  # Lowercase imported as non-lowercase - legacy compatibility
    "N818",  # Exception name should end with Error - legacy compatibility
    "N999",  # Invalid module name - legacy test files
    "PIE810", # Use tuple in startswith - minor stylistic preference
    "PLC0415", # Import outside top-level - intentional lazy loading pattern (see PERFORMANCE.md)
    "PLR0911",  # Too many return statements (complexity)
    "PLR0912",  # Too many branches (complexity)
    "PLR0913",  # Too many arguments (complexity)
    "PLR0915",  # Too many statements (complexity)
    "PLR2004",  # Magic value used in comparison
    "PLW0602",  # Using global without assignment - false positives
    "PLW0603",  # Using global statement (needed for singletons)
    "PLW2901",  # Loop variable reassignment (common pattern)
    "PTH100", # os.path.abspath - too many to fix now
    "PTH101", # os.makedirs - too many to fix now
    "PTH103", # os.mkdirs - too many to fix now
    "PTH108", # os.unlink - too many to fix now
    "PTH112", # os.path.isdir - too many to fix now
    "PTH114", # os.path.islink - too many to fix now
    "PTH117", # os.path.isabs - too many to fix now
    "PTH122", # os.path.splitext - too many to fix now
    "PTH123", # open() should be replaced by Path.open() - too many to fix now
    "PTH202", # os.path.getsize - too many to fix now
    "C401",   # Set comprehension suggestions - readability preference
    "RUF005", # List concatenation suggestions - stylistic preference
    "RUF001", # Ambiguous unicode character - false positives
    "RUF006", # Store reference to asyncio task - intentional fire-and-forget
    "RUF012", # Mutable class attributes without ClassVar - too many to fix now
    "RUF034", # Useless if-else - false positives
    "SIM102", # Use single if statement - can reduce readability
    "SIM103", # Return condition directly - sometimes less clear
    "SIM105", # Use contextlib.suppress - sometimes less explicit
    "SIM108", # Use ternary operator - sometimes less readable
    "SIM112", # Use capitalized environment variable - legacy compatibility
    "SIM113", # Use enumerate - stylistic preference
    "SIM115", # Use context manager - not always applicable
    "SIM117", # Use single with statement - sometimes less readable
    "SIM401", # Use dict.get - stylistic preference
    "UP031",  # Use format specifiers - legacy code compatibility
]

# Exclude paths
exclude = [
    ".git",
    "__pycache__",
    ".venv",
    "venv",
    "env",
    ".env",
    "build",
    "dist",
    "*.egg-info",
    ".pytest_cache",
    ".mypy_cache",
    "node_modules",
    ".tox",
    "migrations",
]

# Per-file ignores
[lint.per-file-ignores]
"__init__.py" = ["F401", "F403"]  # Allow unused imports in __init__
"tests/*" = ["F403", "F405", "F401", "E402", "F841", "PLR0912", "PLR0915", "PLR2004", "DTZ005", "DTZ006", "DTZ007", "PTH123", "PTH207", "PTH109", "PTH107", "PTH110", "PTH113", "PTH118", "PTH120", "PTH119", "PTH116", "PTH102", "PTH208", "N806", "N802", "N803", "F821", "SIM117", "RUF012", "RUF100", "W293", "DTZ003", "B023", "B027", "E722", "F811", "RET504", "PLR0913"]  # More lenient for tests
"scripts/*" = ["T201", "PLR0912", "PLR0915", "PLR2004", "E402", "F841", "PTH123", "DTZ005", "DTZ006", "E722", "E741", "RUF006", "W293", "W291", "F401", "PLR0911", "SIM102", "PTH109", "SIM117", "PLR0913", "B904", "B018", "RUF001", "PTH120", "PTH100", "PTH118", "PTH110", "PTH101"]  # More lenient for scripts
"src/claude_mpm/utils/*" = ["E722", "E741"]  # Allow bare except in utilities
"src/claude_mpm/validation/*" = ["E722"]  # Allow bare except in validation code
"src/claude_mpm/agents/*" = ["PLR0911", "PTH123", "SIM102", "RUF012"]  # Allow agent complexity patterns
"src/claude_mpm/cli/*" = ["SIM102", "PTH123", "E722"]  # Allow CLI patterns
"src/claude_mpm/core/*" = ["RUF012"]  # Allow mutable class attributes in core

# Import settings
[lint.isort]
known-first-party = ["claude_mpm"]
combine-as-imports = true

# McCabe complexity
[lint.mccabe]
max-complexity = 10

# Type checking imports
[lint.flake8-type-checking]
strict = true  # Enforce imports only used for type checking to be in TYPE_CHECKING block