codeprism_lang_python/
analysis.rs

1//! Python-specific code analysis module
2
3// Temporarily allow clippy warnings for Issue #77 - will be cleaned up in future issues
4#![allow(clippy::upper_case_acronyms)]
5#![allow(clippy::enum_variant_names)]
6#![allow(clippy::cmp_owned)]
7
8use anyhow::Result;
9use regex::Regex;
10use std::collections::HashMap;
11
12/// Python metaclass information
13#[derive(Debug, Clone)]
14pub struct MetaclassInfo {
15    pub name: String,
16    pub metaclass_type: String,
17    pub impact: String,
18    pub attributes_modified: Vec<String>,
19    pub methods_modified: Vec<String>,
20}
21
22/// Python decorator information
23#[derive(Debug, Clone)]
24pub struct DecoratorInfo {
25    pub name: String,
26    pub decorator_type: String,
27    pub framework: Option<String>,
28    pub effects: Vec<String>,
29    pub is_factory: bool,
30    pub parameters: Vec<String>,
31}
32
33/// Python inheritance information
34#[derive(Debug, Clone)]
35pub struct InheritanceInfo {
36    pub class_name: String,
37    pub base_classes: Vec<String>,
38    pub mro: Vec<String>,
39    pub has_diamond_inheritance: bool,
40    pub mixins: Vec<String>,
41    pub metaclass: Option<String>,
42}
43
44/// Python security assessment
45#[derive(Debug, Clone)]
46pub struct PythonSecurityAssessment {
47    pub level: SecurityLevel,
48    pub vulnerabilities_detected: Vec<SecurityVulnerability>,
49    pub security_features: Vec<SecurityFeature>,
50    pub recommendations: Vec<String>,
51}
52
53/// Security levels
54#[derive(Debug, Clone)]
55pub enum SecurityLevel {
56    High,       // Well-secured with multiple layers
57    Medium,     // Basic security measures present
58    Low,        // Minimal security implementation
59    Vulnerable, // Security issues detected
60}
61
62/// Security vulnerability information
63#[derive(Debug, Clone)]
64pub struct SecurityVulnerability {
65    pub vulnerability_type: VulnerabilityType,
66    pub severity: VulnerabilitySeverity,
67    pub description: String,
68    pub location: String,
69    pub recommendation: String,
70}
71
72/// Security vulnerability types for Python
73#[derive(Debug, Clone)]
74pub enum VulnerabilityType {
75    SqlInjection,             // Raw SQL queries, unsafe ORM usage
76    CommandInjection,         // subprocess, os.system with user input
77    DeserializationAttack,    // pickle, yaml.load without safe_load
78    PathTraversal,            // os.path.join with user input
79    WeakAuthentication,       // Weak password policies, no 2FA
80    InsecureDataTransmission, // HTTP instead of HTTPS
81    DangerousPickle,          // Unsafe pickle usage
82    UnvalidatedInput,         // Missing input validation
83    InsecureRandomness,       // Using random instead of secrets
84    HardcodedSecrets,         // API keys, passwords in code
85}
86
87/// Vulnerability severity levels
88#[derive(Debug, Clone)]
89pub enum VulnerabilitySeverity {
90    Critical,
91    High,
92    Medium,
93    Low,
94    Info,
95}
96
97/// Security feature information
98#[derive(Debug, Clone)]
99pub struct SecurityFeature {
100    pub feature_type: SecurityFeatureType,
101    pub implementation_quality: ImplementationQuality,
102    pub description: String,
103}
104
105/// Security feature types for Python
106#[derive(Debug, Clone)]
107pub enum SecurityFeatureType {
108    Authentication,         // JWT, OAuth, session-based
109    Authorization,          // RBAC, permissions
110    InputValidation,        // Pydantic, Marshmallow, custom validators
111    CsrfProtection,         // Django CSRF, Flask-WTF
112    DataEncryption,         // cryptography, bcrypt, hashlib
113    SecureHeaders,          // Security headers in responses
114    RateLimiting,           // Flask-Limiter, slowapi
115    SqlInjectionPrevention, // Parameterized queries, ORM usage
116}
117
118/// Implementation quality assessment
119#[derive(Debug, Clone)]
120pub enum ImplementationQuality {
121    Excellent,
122    Good,
123    Adequate,
124    Poor,
125    Missing,
126}
127
128/// Python performance analysis
129#[derive(Debug, Clone)]
130pub struct PythonPerformanceAnalysis {
131    pub overall_score: i32,
132    pub optimizations_detected: Vec<PerformanceOptimization>,
133    pub performance_issues: Vec<PerformanceIssue>,
134    pub recommendations: Vec<String>,
135}
136
137/// Performance optimization information
138#[derive(Debug, Clone)]
139pub struct PerformanceOptimization {
140    pub optimization_type: OptimizationType,
141    pub impact_level: ImpactLevel,
142    pub description: String,
143    pub best_practices_followed: bool,
144}
145
146/// Performance optimization types for Python
147#[derive(Debug, Clone)]
148pub enum OptimizationType {
149    ListComprehension,       // Using list comprehensions vs loops
150    GeneratorUsage,          // Using generators for memory efficiency
151    CachingImplementation,   // functools.cache, Redis, memcached
152    DatabaseOptimization,    // Query optimization, connection pooling
153    AsyncAwaitUsage,         // Proper async/await patterns
154    MemoryOptimization,      // __slots__, weak references
155    AlgorithmicOptimization, // Using efficient algorithms and data structures
156}
157
158/// Performance issue information  
159#[derive(Debug, Clone)]
160pub struct PerformanceIssue {
161    pub issue_type: PerformanceIssueType,
162    pub severity: IssueSeverity,
163    pub description: String,
164    pub recommendation: String,
165}
166
167/// Performance issue types for Python
168#[derive(Debug, Clone)]
169pub enum PerformanceIssueType {
170    InEfficientLoops,    // Nested loops, unnecessary iterations
171    MemoryLeaks,         // Circular references, unclosed resources
172    BlockingOperations,  // Sync operations in async context
173    InefficientQueries,  // N+1 queries, missing joins
174    LargeDataStructures, // Loading large datasets into memory
175    UnoptimizedImports,  // Importing heavy modules unnecessarily
176    GilContention,       // Threading inefficiencies
177}
178
179/// Issue severity levels
180#[derive(Debug, Clone)]
181pub enum IssueSeverity {
182    Critical,
183    High,
184    Medium,
185    Low,
186}
187
188/// Impact levels for performance metrics
189#[derive(Debug, Clone)]
190pub enum ImpactLevel {
191    High,     // Significant performance impact
192    Medium,   // Moderate performance impact
193    Low,      // Minor performance impact
194    Positive, // Performance optimization
195}
196
197/// Enhanced Python framework analysis
198#[derive(Debug, Clone)]
199pub struct PythonFrameworkInfo {
200    pub name: String,
201    pub confidence: f32,
202    pub version_detected: Option<String>,
203    pub features_used: Vec<String>,
204    pub best_practices: Vec<String>,
205    pub framework_specific_analysis: FrameworkSpecificAnalysis,
206}
207
208/// Framework-specific analysis
209#[derive(Debug, Clone)]
210pub enum FrameworkSpecificAnalysis {
211    Django(DjangoAnalysis),
212    Flask(FlaskAnalysis),
213    FastAPI(FastAPIAnalysis),
214    Pytest(PytestAnalysis),
215    Celery(CeleryAnalysis),
216}
217
218/// Django-specific analysis
219#[derive(Debug, Clone)]
220pub struct DjangoAnalysis {
221    pub models_analysis: Vec<DjangoModelInfo>,
222    pub views_analysis: Vec<DjangoViewInfo>,
223    pub middleware_usage: Vec<String>,
224    pub security_middleware: Vec<String>,
225    pub signals_usage: Vec<String>,
226    pub admin_customization: bool,
227}
228
229/// Django model information
230#[derive(Debug, Clone)]
231pub struct DjangoModelInfo {
232    pub name: String,
233    pub fields: Vec<DjangoFieldInfo>,
234    pub relationships: Vec<String>,
235    pub custom_managers: bool,
236    pub meta_options: Vec<String>,
237}
238
239/// Django field information
240#[derive(Debug, Clone)]
241pub struct DjangoFieldInfo {
242    pub name: String,
243    pub field_type: String,
244    pub constraints: Vec<String>,
245    pub indexes: bool,
246}
247
248/// Django view information
249#[derive(Debug, Clone)]
250pub struct DjangoViewInfo {
251    pub name: String,
252    pub view_type: DjangoViewType,
253    pub permissions: Vec<String>,
254    pub mixins: Vec<String>,
255}
256
257/// Django view types
258#[derive(Debug, Clone)]
259pub enum DjangoViewType {
260    FunctionBased,
261    ClassBased,
262    GenericView,
263    ViewSet,
264}
265
266/// Flask-specific analysis
267#[derive(Debug, Clone)]
268pub struct FlaskAnalysis {
269    pub blueprints: Vec<FlaskBlueprintInfo>,
270    pub extensions: Vec<String>,
271    pub error_handlers: Vec<String>,
272    pub template_usage: bool,
273    pub session_management: bool,
274}
275
276/// Flask blueprint information
277#[derive(Debug, Clone)]
278pub struct FlaskBlueprintInfo {
279    pub name: String,
280    pub url_prefix: Option<String>,
281    pub routes: Vec<FlaskRouteInfo>,
282}
283
284/// Flask route information
285#[derive(Debug, Clone)]
286pub struct FlaskRouteInfo {
287    pub path: String,
288    pub methods: Vec<String>,
289    pub endpoint: String,
290    pub view_function: String,
291}
292
293/// FastAPI-specific analysis
294#[derive(Debug, Clone)]
295pub struct FastAPIAnalysis {
296    pub router_usage: Vec<FastAPIRouterInfo>,
297    pub dependency_injection: Vec<String>,
298    pub background_tasks: bool,
299    pub websocket_endpoints: Vec<String>,
300    pub middleware: Vec<String>,
301    pub response_models: Vec<String>,
302}
303
304/// FastAPI router information
305#[derive(Debug, Clone)]
306pub struct FastAPIRouterInfo {
307    pub prefix: Option<String>,
308    pub tags: Vec<String>,
309    pub endpoints: Vec<FastAPIEndpointInfo>,
310}
311
312/// FastAPI endpoint information
313#[derive(Debug, Clone)]
314pub struct FastAPIEndpointInfo {
315    pub path: String,
316    pub method: String,
317    pub response_model: Option<String>,
318    pub dependencies: Vec<String>,
319}
320
321/// Pytest-specific analysis
322#[derive(Debug, Clone)]
323pub struct PytestAnalysis {
324    pub fixtures: Vec<PytestFixtureInfo>,
325    pub parametrized_tests: Vec<String>,
326    pub markers: Vec<String>,
327    pub plugins: Vec<String>,
328    pub coverage_setup: bool,
329}
330
331/// Pytest fixture information
332#[derive(Debug, Clone)]
333pub struct PytestFixtureInfo {
334    pub name: String,
335    pub scope: String,
336    pub autouse: bool,
337    pub dependencies: Vec<String>,
338}
339
340/// Celery-specific analysis
341#[derive(Debug, Clone)]
342pub struct CeleryAnalysis {
343    pub tasks: Vec<CeleryTaskInfo>,
344    pub brokers: Vec<String>,
345    pub result_backends: Vec<String>,
346    pub routing: Vec<String>,
347    pub monitoring: bool,
348}
349
350/// Celery task information
351#[derive(Debug, Clone)]
352pub struct CeleryTaskInfo {
353    pub name: String,
354    pub task_type: CeleryTaskType,
355    pub retry_policy: Option<String>,
356    pub rate_limit: Option<String>,
357}
358
359/// Celery task types
360#[derive(Debug, Clone)]
361pub enum CeleryTaskType {
362    Regular,
363    Periodic,
364    Chain,
365    Group,
366    Chord,
367}
368
369/// Python type hint analysis result
370#[derive(Debug, Clone)]
371pub struct PythonTypeHintAnalysis {
372    pub overall_coverage: f32,
373    pub type_coverage_score: TypeCoverageScore,
374    pub type_hints_detected: Vec<TypeHintInfo>,
375    pub type_safety_issues: Vec<TypeSafetyIssue>,
376    pub modern_type_features: Vec<ModernTypeFeature>,
377    pub recommendations: Vec<String>,
378}
379
380/// Type coverage scoring
381#[derive(Debug, Clone)]
382pub enum TypeCoverageScore {
383    Excellent, // 90%+ coverage
384    Good,      // 70-89% coverage
385    Fair,      // 50-69% coverage
386    Poor,      // 30-49% coverage
387    Minimal,   // <30% coverage
388}
389
390/// Type hint information
391#[derive(Debug, Clone)]
392pub struct TypeHintInfo {
393    pub location: String,
394    pub hint_type: TypeHintType,
395    pub complexity: TypeComplexity,
396    pub is_generic: bool,
397    pub has_constraints: bool,
398    pub python_version_required: String,
399}
400
401/// Type hint types
402#[derive(Debug, Clone)]
403pub enum TypeHintType {
404    SimpleType(String),             // int, str, bool
405    UnionType(Vec<String>),         // Union[str, int] or str | int
406    GenericType(GenericTypeInfo),   // List[T], Dict[K, V]
407    ProtocolType(String),           // Protocol for structural typing
408    LiteralType(Vec<String>),       // Literal['value1', 'value2']
409    CallableType(CallableTypeInfo), // Callable[[int, str], bool]
410    TypeVarType(TypeVarInfo),       // TypeVar constraints and bounds
411    OptionalType(String),           // Optional[str] or str | None
412    FinalType(String),              // Final[int]
413    TypedDictType(TypedDictInfo),   // TypedDict for structured dicts
414}
415
416/// Generic type information
417#[derive(Debug, Clone)]
418pub struct GenericTypeInfo {
419    pub base_type: String,            // List, Dict, Set, etc.
420    pub type_parameters: Vec<String>, // [T] or [K, V]
421    pub is_covariant: bool,
422    pub is_contravariant: bool,
423}
424
425/// Callable type information
426#[derive(Debug, Clone)]
427pub struct CallableTypeInfo {
428    pub parameter_types: Vec<String>,
429    pub return_type: String,
430    pub is_async: bool,
431}
432
433/// TypeVar information
434#[derive(Debug, Clone)]
435pub struct TypeVarInfo {
436    pub name: String,
437    pub bounds: Vec<String>,
438    pub constraints: Vec<String>,
439    pub covariant: bool,
440    pub contravariant: bool,
441}
442
443/// TypedDict information
444#[derive(Debug, Clone)]
445pub struct TypedDictInfo {
446    pub name: String,
447    pub fields: Vec<TypedDictField>,
448    pub total: bool, // Whether all fields are required
449}
450
451/// TypedDict field information
452#[derive(Debug, Clone)]
453pub struct TypedDictField {
454    pub name: String,
455    pub field_type: String,
456    pub required: bool,
457}
458
459/// Type complexity assessment
460#[derive(Debug, Clone)]
461pub enum TypeComplexity {
462    Simple,   // Basic types like int, str
463    Moderate, // Union types, Optional
464    Complex,  // Generic types with multiple parameters
465    Advanced, // Complex nested generics, Protocols
466}
467
468/// Type safety issues
469#[derive(Debug, Clone)]
470pub struct TypeSafetyIssue {
471    pub issue_type: TypeSafetyIssueType,
472    pub severity: TypeSafetySeverity,
473    pub location: String,
474    pub description: String,
475    pub recommendation: String,
476}
477
478/// Type safety issue types
479#[derive(Debug, Clone)]
480pub enum TypeSafetyIssueType {
481    AnyTypeOveruse,         // Too many Any types
482    MissingTypeHints,       // Functions without type hints
483    InconsistentTypes,      // Type inconsistencies
484    TypeIgnoreOveruse,      // Too many # type: ignore comments
485    WrongTypeHintSyntax,    // Incorrect type hint syntax
486    DeprecatedTypingSyntax, // Using old typing syntax
487    UnreachableCode,        // Dead code due to type narrowing
488    TypeVarianceIssue,      // Covariance/contravariance problems
489}
490
491/// Type safety severity levels
492#[derive(Debug, Clone)]
493pub enum TypeSafetySeverity {
494    Error,   // Type errors that would cause runtime issues
495    Warning, // Type inconsistencies that should be addressed
496    Info,    // Suggestions for improvement
497}
498
499/// Modern type features (Python 3.8+)
500#[derive(Debug, Clone)]
501pub struct ModernTypeFeature {
502    pub feature_type: ModernTypeFeatureType,
503    pub python_version: String,
504    pub usage_count: usize,
505    pub description: String,
506    pub is_best_practice: bool,
507}
508
509/// Modern type feature types
510#[derive(Debug, Clone)]
511pub enum ModernTypeFeatureType {
512    PositionalOnlyParams, // def func(arg, /) -> str:
513    UnionSyntaxPy310,     // str | int instead of Union[str, int]
514    TypedDict,            // TypedDict for structured dictionaries
515    FinalType,            // Final[int] = 42
516    LiteralType,          // Literal['red', 'green', 'blue']
517    ProtocolType,         // Protocol for structural typing
518    TypeGuard,            // TypeGuard for type narrowing
519    OverloadDecorator,    // @overload for function overloading
520    GenericAlias,         // list[int] instead of List[int] (Python 3.9+)
521    ParamSpec,            // ParamSpec for callable signatures (Python 3.10+)
522    TypeVarTuple,         // TypeVarTuple for variadic generics (Python 3.11+)
523}
524
525/// Pattern for type hint detection
526#[derive(Debug, Clone)]
527struct TypeHintPattern {
528    name: String,
529    pattern: Regex,
530    hint_type: String,
531    complexity: TypeComplexity,
532    python_version: String,
533}
534
535/// Python async/await pattern analysis result
536#[derive(Debug, Clone)]
537pub struct PythonAsyncAwaitAnalysis {
538    pub overall_async_score: i32,
539    pub async_functions_detected: Vec<AsyncFunctionInfo>,
540    pub await_usage_patterns: Vec<AwaitUsageInfo>,
541    pub concurrency_patterns: Vec<ConcurrencyPatternInfo>,
542    pub async_performance_issues: Vec<AsyncPerformanceIssue>,
543    pub async_security_issues: Vec<AsyncSecurityIssue>,
544    pub modern_async_features: Vec<ModernAsyncFeature>,
545    pub recommendations: Vec<String>,
546}
547
548/// Async function information
549#[derive(Debug, Clone)]
550pub struct AsyncFunctionInfo {
551    pub name: String,
552    pub function_type: AsyncFunctionType,
553    pub complexity: AsyncComplexity,
554    pub coroutine_type: CoroutineType,
555    pub error_handling: AsyncErrorHandling,
556    pub has_timeout: bool,
557    pub uses_context_manager: bool,
558    pub location: String,
559}
560
561/// Types of async functions
562#[derive(Debug, Clone)]
563pub enum AsyncFunctionType {
564    RegularAsync,        // async def function()
565    AsyncGenerator,      // async def with yield
566    AsyncContextManager, // __aenter__, __aexit__
567    AsyncIterator,       // __aiter__, __anext__
568    AsyncProperty,       // @async_property
569    AsyncDecorator,      // Decorates with async functionality
570}
571
572/// Async function complexity
573#[derive(Debug, Clone)]
574pub enum AsyncComplexity {
575    Simple,   // Single await or simple operations
576    Moderate, // Multiple awaits, basic control flow
577    Complex,  // Nested awaits, exception handling
578    Advanced, // Complex concurrency patterns, resource management
579}
580
581/// Coroutine type classification
582#[derive(Debug, Clone)]
583pub enum CoroutineType {
584    Native,            // Native Python coroutines
585    Framework(String), // Framework-specific (asyncio, trio, curio)
586    Generator,         // Generator-based coroutines (deprecated)
587    Hybrid,            // Mixed native and framework
588}
589
590/// Async error handling assessment
591#[derive(Debug, Clone)]
592pub enum AsyncErrorHandling {
593    None,    // No error handling
594    Basic,   // Simple try/catch
595    Timeout, // Includes timeout handling
596    Robust,  // Comprehensive error handling with retries
597}
598
599/// Await usage information
600#[derive(Debug, Clone)]
601pub struct AwaitUsageInfo {
602    pub location: String,
603    pub context: AwaitContext,
604    pub usage_pattern: AwaitUsagePattern,
605    pub is_valid: bool,
606    pub potential_issues: Vec<AwaitIssue>,
607}
608
609/// Context where await is used
610#[derive(Debug, Clone)]
611pub enum AwaitContext {
612    AsyncFunction,       // Inside async def
613    AsyncGenerator,      // Inside async generator
614    AsyncContextManager, // Inside async context manager
615    AsyncIterator,       // Inside async iterator
616    SyncContext,         // Invalid: inside sync function
617    Comprehension,       // Invalid: inside comprehension
618    Lambda,              // Invalid: inside lambda
619}
620
621/// Await usage patterns
622#[derive(Debug, Clone)]
623pub enum AwaitUsagePattern {
624    SingleAwait,      // Single await expression
625    SequentialAwaits, // Multiple sequential awaits
626    ConditionalAwait, // Await in conditional
627    NestedAwait,      // Await inside await
628    GatheredAwait,    // Part of asyncio.gather()
629    ConcurrentAwait,  // Concurrent execution pattern
630}
631
632/// Await usage issues
633#[derive(Debug, Clone)]
634pub enum AwaitIssue {
635    IllegalContext, // await in illegal context
636    MissingAwait,   // Missing await on coroutine
637    BlockingCall,   // Blocking call in async context
638    SyncInAsync,    // Sync operation in async function
639    ResourceLeak,   // Potential resource leak
640    TimeoutMissing, // Missing timeout handling
641}
642
643/// Concurrency pattern information
644#[derive(Debug, Clone)]
645pub struct ConcurrencyPatternInfo {
646    pub pattern_type: ConcurrencyPatternType,
647    pub usage_quality: ConcurrencyUsageQuality,
648    pub performance_impact: AsyncPerformanceImpact,
649    pub location: String,
650    pub best_practices_followed: bool,
651}
652
653/// Types of concurrency patterns
654#[derive(Debug, Clone)]
655pub enum ConcurrencyPatternType {
656    AsyncioGather,     // asyncio.gather() for concurrent execution
657    AsyncioWait,       // asyncio.wait() for coordination
658    AsyncioQueue,      // asyncio.Queue for producer-consumer
659    AsyncioSemaphore,  // asyncio.Semaphore for rate limiting
660    AsyncioLock,       // asyncio.Lock for synchronization
661    TaskGroup,         // Python 3.11+ TaskGroup
662    ConcurrentFutures, // concurrent.futures integration
663    AsyncioTimeout,    // asyncio.timeout() context manager
664    AsyncioEvent,      // asyncio.Event for coordination
665    AsyncioCondition,  // asyncio.Condition for complex coordination
666}
667
668/// Quality of concurrency usage
669#[derive(Debug, Clone)]
670pub enum ConcurrencyUsageQuality {
671    Excellent, // Optimal usage with best practices
672    Good,      // Correct usage with minor optimizations possible
673    Adequate,  // Functional but suboptimal
674    Poor,      // Problematic usage that should be improved
675    Dangerous, // Usage that can cause deadlocks or race conditions
676}
677
678/// Performance impact of async patterns
679#[derive(Debug, Clone)]
680pub enum AsyncPerformanceImpact {
681    Positive, // Improves performance
682    Neutral,  // No significant impact
683    Negative, // Reduces performance
684    Critical, // Severely impacts performance
685}
686
687/// Async-specific performance issues
688#[derive(Debug, Clone)]
689pub struct AsyncPerformanceIssue {
690    pub issue_type: AsyncPerformanceIssueType,
691    pub severity: AsyncIssueSeverity,
692    pub location: String,
693    pub description: String,
694    pub recommendation: String,
695    pub estimated_impact: AsyncPerformanceImpact,
696}
697
698/// Types of async performance issues
699#[derive(Debug, Clone)]
700pub enum AsyncPerformanceIssueType {
701    BlockingIOInAsync,     // Sync I/O operations in async functions
702    EventLoopBlocking,     // Operations that block the event loop
703    GILContentionAsync,    // GIL contention in async code
704    AwaitInLoop,           // Inefficient await in loop
705    MissingConcurrency,    // Sequential execution where concurrent is possible
706    ResourceLeakAsync,     // Async resource leaks
707    SyncWrapperOveruse,    // Overuse of sync-to-async wrappers
708    AsyncioSubprocessSync, // Sync subprocess calls in async context
709    DatabaseBlockingAsync, // Blocking database calls in async functions
710    SlowAsyncGenerator,    // Inefficient async generators
711}
712
713/// Async issue severity levels
714#[derive(Debug, Clone)]
715pub enum AsyncIssueSeverity {
716    Critical, // Breaks async functionality
717    High,     // Significant performance impact
718    Medium,   // Moderate impact on performance
719    Low,      // Minor optimization opportunity
720    Info,     // Best practice suggestion
721}
722
723/// Async-specific security issues
724#[derive(Debug, Clone)]
725pub struct AsyncSecurityIssue {
726    pub issue_type: AsyncSecurityIssueType,
727    pub severity: AsyncSecuritySeverity,
728    pub location: String,
729    pub description: String,
730    pub recommendation: String,
731}
732
733/// Types of async security issues
734#[derive(Debug, Clone)]
735pub enum AsyncSecurityIssueType {
736    AsyncRaceCondition,     // Race conditions in async code
737    SharedStateNoLock,      // Shared mutable state without locking
738    AsyncTimeoutVuln,       // Missing timeouts enabling DoS
739    TaskCancellationLeak,   // Improper task cancellation
740    AsyncResourceExposure,  // Resource exposure through async operations
741    EventLoopPoisoning,     // Event loop manipulation attacks
742    AsyncPickleVuln,        // Pickle vulnerabilities in async context
743    ConcurrentModification, // Concurrent modification without protection
744}
745
746/// Async security severity levels
747#[derive(Debug, Clone)]
748pub enum AsyncSecuritySeverity {
749    Critical, // Exploitable security vulnerability
750    High,     // Significant security risk
751    Medium,   // Moderate security concern
752    Low,      // Minor security consideration
753    Info,     // Security best practice
754}
755
756/// Modern async features (Python 3.7+)
757#[derive(Debug, Clone)]
758pub struct ModernAsyncFeature {
759    pub feature_type: ModernAsyncFeatureType,
760    pub python_version: String,
761    pub usage_count: usize,
762    pub description: String,
763    pub is_best_practice: bool,
764}
765
766/// Types of modern async features
767#[derive(Debug, Clone)]
768pub enum ModernAsyncFeatureType {
769    AsyncContextManager, // async with statements
770    TaskGroups,          // Python 3.11+ TaskGroup
771    AsyncioTimeout,      // asyncio.timeout() (Python 3.11+)
772    AsyncIterators,      // async for loops
773    AsyncGenerators,     // async generators with yield
774    AsyncComprehensions, // Async list/dict/set comprehensions
775    ContextVars,         // contextvars for async context
776    AsyncioRun,          // asyncio.run() for main entry point
777    AsyncDecorators,     // Custom async decorators
778    StreamAPI,           // asyncio streams for I/O
779    SubprocessAsync,     // asyncio subprocess for non-blocking process execution
780}
781
782/// Pattern for async detection
783#[derive(Debug, Clone)]
784struct AsyncPattern {
785    name: String,
786    pattern: Regex,
787    pattern_type: String,
788    performance_impact: AsyncPerformanceImpact,
789}
790
791/// Python package dependency analysis result
792#[derive(Debug, Clone)]
793pub struct PythonPackageDependencyAnalysis {
794    pub overall_health_score: i32,
795    pub requirements_files: Vec<RequirementsFileInfo>,
796    pub dependencies: Vec<RequirementInfo>,
797    pub dependency_issues: Vec<DependencyIssue>,
798    pub virtual_environments: Vec<VirtualEnvironmentInfo>,
799    pub import_analysis: Vec<ImportAnalysisInfo>,
800    pub security_vulnerabilities: Vec<SecurityVulnerabilityInfo>,
801    pub license_analysis: Vec<LicenseInfo>,
802    pub recommendations: Vec<String>,
803}
804
805/// Requirements file information
806#[derive(Debug, Clone)]
807pub struct RequirementsFileInfo {
808    pub file_path: String,
809    pub file_type: RequirementsFileType,
810    pub dependencies_count: usize,
811    pub has_version_pins: bool,
812    pub has_hashes: bool,
813    pub uses_constraints: bool,
814    pub quality_score: DependencyQualityScore,
815}
816
817/// Requirements file types
818#[derive(Debug, Clone)]
819pub enum RequirementsFileType {
820    RequirementsTxt, // requirements.txt
821    PyprojectToml,   // pyproject.toml with dependencies
822    SetupPy,         // setup.py with install_requires
823    Pipfile,         // Pipfile for pipenv
824    PipfileLock,     // Pipfile.lock with locked versions
825    PoetryLock,      // poetry.lock for poetry
826    CondaYml,        // environment.yml for conda
827    SetupCfg,        // setup.cfg with install_requires
828}
829
830/// Individual requirement information
831#[derive(Debug, Clone)]
832pub struct RequirementInfo {
833    pub name: String,
834    pub version_spec: String,
835    pub source: RequirementSource,
836    pub is_dev_dependency: bool,
837    pub is_optional: bool,
838    pub extras: Vec<String>,
839    pub markers: Vec<String>,
840    pub metadata: PackageMetadata,
841}
842
843/// Requirement source types
844#[derive(Debug, Clone)]
845pub enum RequirementSource {
846    PyPI,                // Standard PyPI package
847    Git(String),         // Git repository URL
848    Local(String),       // Local file path
849    URL(String),         // Direct URL
850    VCS(String, String), // Version control (type, url)
851}
852
853/// Package metadata information
854#[derive(Debug, Clone)]
855pub struct PackageMetadata {
856    pub description: String,
857    pub author: String,
858    pub license: String,
859    pub homepage: Option<String>,
860    pub documentation: Option<String>,
861    pub last_updated: Option<String>,
862    pub download_count: Option<u64>,
863    pub maintenance_status: MaintenanceStatus,
864}
865
866/// Package maintenance status
867#[derive(Debug, Clone)]
868pub enum MaintenanceStatus {
869    Active,     // Recently updated, active development
870    Maintained, // Occasional updates, bug fixes
871    Stable,     // Mature, infrequent updates
872    Deprecated, // No longer maintained
873    Abandoned,  // No updates for extended period
874    Unknown,    // Unable to determine status
875}
876
877/// Dependency quality scoring
878#[derive(Debug, Clone)]
879pub enum DependencyQualityScore {
880    Excellent, // 90-100: Well-managed, secure, up-to-date
881    Good,      // 70-89: Good practices, minor issues
882    Fair,      // 50-69: Adequate, some improvements needed
883    Poor,      // 30-49: Multiple issues, needs attention
884    Critical,  // 0-29: Major problems, immediate action required
885}
886
887/// Dependency issues
888#[derive(Debug, Clone)]
889pub struct DependencyIssue {
890    pub issue_type: DependencyIssueType,
891    pub severity: DependencyIssueSeverity,
892    pub affected_packages: Vec<String>,
893    pub description: String,
894    pub recommendation: String,
895    pub auto_fixable: bool,
896}
897
898/// Dependency issue types
899#[derive(Debug, Clone)]
900pub enum DependencyIssueType {
901    VersionConflict,        // Conflicting version requirements
902    CircularDependency,     // Circular dependency detected
903    UnusedDependency,       // Declared but not imported
904    MissingDependency,      // Imported but not declared
905    SecurityVulnerability,  // Known security issue
906    LicenseIncompatibility, // Incompatible licenses
907    DeprecatedPackage,      // Package is deprecated
908    UnpinnedVersion,        // Version not pinned for production
909    OutdatedVersion,        // Newer version available
910    DevDependencyInProd,    // Dev dependency in production requirements
911    DuplicateDependency,    // Same package in multiple files
912}
913
914/// Dependency issue severity
915#[derive(Debug, Clone)]
916pub enum DependencyIssueSeverity {
917    Critical, // Security vulnerabilities, license violations
918    High,     // Version conflicts, missing dependencies
919    Medium,   // Deprecated packages, outdated versions
920    Low,      // Unused dependencies, minor optimizations
921    Info,     // Best practice suggestions
922}
923
924/// Virtual environment information
925#[derive(Debug, Clone)]
926pub struct VirtualEnvironmentInfo {
927    pub env_type: VirtualEnvironmentType,
928    pub location: String,
929    pub python_version: String,
930    pub is_active: bool,
931    pub packages_count: usize,
932    pub env_variables: Vec<EnvironmentVariable>,
933    pub configuration: VirtualEnvironmentConfig,
934}
935
936/// Virtual environment types
937#[derive(Debug, Clone)]
938pub enum VirtualEnvironmentType {
939    Venv,           // Python venv
940    Virtualenv,     // virtualenv package
941    Conda,          // Anaconda/Miniconda
942    Pipenv,         // Pipenv virtual environment
943    Poetry,         // Poetry virtual environment
944    Docker,         // Docker container environment
945    Pyenv,          // pyenv version management
946    Custom(String), // Custom environment type
947}
948
949/// Environment variable information
950#[derive(Debug, Clone)]
951pub struct EnvironmentVariable {
952    pub name: String,
953    pub value: String,
954    pub is_sensitive: bool,
955    pub purpose: EnvironmentVariablePurpose,
956}
957
958/// Environment variable purposes
959#[derive(Debug, Clone)]
960pub enum EnvironmentVariablePurpose {
961    Configuration, // Application configuration
962    Secret,        // API keys, passwords
963    Path,          // PYTHONPATH, PATH modifications
964    Development,   // Development-specific settings
965    Production,    // Production environment settings
966    Testing,       // Test configuration
967    Unknown,       // Unable to categorize
968}
969
970/// Virtual environment configuration
971#[derive(Debug, Clone)]
972pub struct VirtualEnvironmentConfig {
973    pub isolated: bool,
974    pub system_site_packages: bool,
975    pub pip_version: Option<String>,
976    pub setuptools_version: Option<String>,
977    pub custom_configurations: Vec<String>,
978}
979
980/// Import analysis information
981#[derive(Debug, Clone)]
982pub struct ImportAnalysisInfo {
983    pub import_statement: String,
984    pub import_type: ImportType,
985    pub module_category: ModuleCategory,
986    pub usage_count: usize,
987    pub is_unused: bool,
988    pub import_issues: Vec<ImportIssue>,
989    pub optimization_suggestions: Vec<String>,
990}
991
992/// Import types
993#[derive(Debug, Clone)]
994pub enum ImportType {
995    StandardImport,    // import module
996    FromImport,        // from module import item
997    StarImport,        // from module import *
998    AliasImport,       // import module as alias
999    RelativeImport,    // from .module import item
1000    ConditionalImport, // Import inside if/try block
1001    DynamicImport,     // importlib.import_module()
1002}
1003
1004/// Module categories
1005#[derive(Debug, Clone)]
1006pub enum ModuleCategory {
1007    StandardLibrary, // Built-in Python modules
1008    ThirdParty,      // External packages from PyPI
1009    Local,           // Local project modules
1010    BuiltIn,         // Built-in functions and types
1011    Unknown,         // Unable to categorize
1012}
1013
1014/// Import issues
1015#[derive(Debug, Clone, PartialEq)]
1016pub enum ImportIssue {
1017    CircularImport,      // Circular import detected
1018    StarImportDangerous, // from module import * is problematic
1019    UnusedImport,        // Import not used in code
1020    RedundantImport,     // Import duplicated
1021    WrongImportOrder,    // PEP 8 import order violation
1022    MissingImport,       // Required import not found
1023    SlowImport,          // Import is known to be slow
1024    DeprecatedImport,    // Importing deprecated module
1025}
1026
1027/// Security vulnerability information
1028#[derive(Debug, Clone)]
1029pub struct SecurityVulnerabilityInfo {
1030    pub cve_id: Option<String>,
1031    pub advisory_id: Option<String>,
1032    pub package_name: String,
1033    pub affected_versions: Vec<String>,
1034    pub fixed_version: Option<String>,
1035    pub severity: SecurityVulnerabilitySeverity,
1036    pub vulnerability_type: VulnerabilityCategory,
1037    pub description: String,
1038    pub references: Vec<String>,
1039    pub published_date: Option<String>,
1040    pub last_modified: Option<String>,
1041}
1042
1043/// Security vulnerability severity (CVSS-based)
1044#[derive(Debug, Clone)]
1045pub enum SecurityVulnerabilitySeverity {
1046    Critical, // CVSS 9.0-10.0
1047    High,     // CVSS 7.0-8.9
1048    Medium,   // CVSS 4.0-6.9
1049    Low,      // CVSS 0.1-3.9
1050    None,     // CVSS 0.0
1051    Unknown,  // Severity not available
1052}
1053
1054/// Vulnerability categories
1055#[derive(Debug, Clone)]
1056pub enum VulnerabilityCategory {
1057    CodeExecution,         // Remote or arbitrary code execution
1058    SqlInjection,          // SQL injection vulnerabilities
1059    XSS,                   // Cross-site scripting
1060    CSRF,                  // Cross-site request forgery
1061    PathTraversal,         // Directory traversal attacks
1062    Deserialization,       // Unsafe deserialization
1063    Cryptographic,         // Cryptographic weaknesses
1064    DoS,                   // Denial of service
1065    PrivilegeEscalation,   // Privilege escalation
1066    InformationDisclosure, // Information disclosure
1067    InputValidation,       // Input validation issues
1068    AuthenticationBypass,  // Authentication bypass
1069    Other(String),         // Other vulnerability types
1070}
1071
1072/// License information
1073#[derive(Debug, Clone)]
1074pub struct LicenseInfo {
1075    pub package_name: String,
1076    pub license_type: LicenseType,
1077    pub license_text: Option<String>,
1078    pub compatibility: LicenseCompatibility,
1079    pub commercial_use_allowed: bool,
1080    pub distribution_allowed: bool,
1081    pub modification_allowed: bool,
1082    pub patent_grant: bool,
1083    pub copyleft: bool,
1084}
1085
1086/// License types
1087#[derive(Debug, Clone)]
1088pub enum LicenseType {
1089    MIT,
1090    Apache2,
1091    GPL2,
1092    GPL3,
1093    BSD2Clause,
1094    BSD3Clause,
1095    LGPL,
1096    Mozilla,
1097    Unlicense,
1098    Proprietary,
1099    Custom(String),
1100    Unknown,
1101}
1102
1103/// License compatibility assessment
1104#[derive(Debug, Clone)]
1105pub enum LicenseCompatibility {
1106    Compatible,              // Fully compatible with project license
1107    ConditionallyCompatible, // Compatible under certain conditions
1108    Incompatible,            // License conflict detected
1109    RequiresReview,          // Manual review required
1110    Unknown,                 // Unable to determine compatibility
1111}
1112
1113/// Pattern for dependency detection
1114#[derive(Debug, Clone)]
1115struct DependencyPattern {
1116    name: String,
1117    pattern: Regex,
1118    #[allow(dead_code)] // Will be used for dependency file type analysis
1119    file_type: RequirementsFileType,
1120    extraction_method: String,
1121}
1122
1123/// Modern Python features analysis result
1124#[derive(Debug, Clone)]
1125pub struct ModernPythonFeatureAnalysis {
1126    pub overall_modernity_score: i32,
1127    pub python_version_detected: PythonVersionDetected,
1128    pub dataclass_features: Vec<DataclassInfo>,
1129    pub context_manager_features: Vec<ContextManagerInfo>,
1130    pub fstring_features: Vec<FStringInfo>,
1131    pub pattern_matching_features: Vec<PatternMatchingInfo>,
1132    pub generator_features: Vec<GeneratorInfo>,
1133    pub decorator_features: Vec<ModernDecoratorInfo>,
1134    pub modern_syntax_features: Vec<ModernSyntaxInfo>,
1135    pub recommendations: Vec<String>,
1136}
1137
1138/// Python version detection
1139#[derive(Debug, Clone)]
1140pub struct PythonVersionDetected {
1141    pub minimum_version: String,
1142    pub features_by_version: Vec<VersionFeature>,
1143    pub compatibility_issues: Vec<CompatibilityIssue>,
1144}
1145
1146/// Version-specific feature
1147#[derive(Debug, Clone)]
1148pub struct VersionFeature {
1149    pub feature_name: String,
1150    pub python_version: String,
1151    pub usage_count: usize,
1152    pub is_best_practice: bool,
1153}
1154
1155/// Compatibility issue
1156#[derive(Debug, Clone)]
1157pub struct CompatibilityIssue {
1158    pub issue_type: CompatibilityIssueType,
1159    pub severity: CompatibilitySeverity,
1160    pub feature_name: String,
1161    pub required_version: String,
1162    pub description: String,
1163    pub recommendation: String,
1164}
1165
1166/// Compatibility issue types
1167#[derive(Debug, Clone)]
1168pub enum CompatibilityIssueType {
1169    VersionMismatch,   // Feature requires newer Python version
1170    DeprecatedFeature, // Feature is deprecated
1171    SyntaxError,       // Syntax not supported in target version
1172    ImportError,       // Module not available in target version
1173    BehaviorChange,    // Feature behavior changed between versions
1174}
1175
1176/// Compatibility severity
1177#[derive(Debug, Clone)]
1178pub enum CompatibilitySeverity {
1179    Critical, // Code will not run
1180    High,     // Major functionality affected
1181    Medium,   // Minor issues or warnings
1182    Low,      // Style or performance recommendations
1183    Info,     // Informational only
1184}
1185
1186/// Dataclass analysis information
1187#[derive(Debug, Clone)]
1188pub struct DataclassInfo {
1189    pub class_name: String,
1190    pub dataclass_type: DataclassType,
1191    pub fields: Vec<DataclassField>,
1192    pub features_used: Vec<DataclassFeature>,
1193    pub complexity: FeatureComplexity,
1194    pub best_practices_score: i32,
1195    pub recommendations: Vec<String>,
1196}
1197
1198/// Dataclass types
1199#[derive(Debug, Clone, PartialEq)]
1200pub enum DataclassType {
1201    StandardDataclass, // @dataclass
1202    PydanticModel,     // Pydantic BaseModel
1203    NamedTuple,        // typing.NamedTuple
1204    AttrsClass,        // attrs @attr.s
1205    SimpleNamespace,   // types.SimpleNamespace
1206}
1207
1208/// Dataclass field information
1209#[derive(Debug, Clone)]
1210pub struct DataclassField {
1211    pub name: String,
1212    pub field_type: String,
1213    pub has_default: bool,
1214    pub is_optional: bool,
1215    pub validation_rules: Vec<String>,
1216    pub metadata: Vec<String>,
1217}
1218
1219/// Dataclass features
1220#[derive(Debug, Clone, PartialEq)]
1221pub enum DataclassFeature {
1222    FrozenClass,        // frozen=True
1223    InitGeneration,     // init=True/False
1224    ReprGeneration,     // repr=True/False
1225    EqGeneration,       // eq=True/False
1226    OrderGeneration,    // order=True
1227    HashGeneration,     // unsafe_hash=True
1228    SlotsUsage,         // __slots__
1229    PostInitProcessing, // __post_init__
1230    FieldFactories,     // default_factory
1231    KwOnlyFields,       // kw_only fields
1232}
1233
1234/// Context manager analysis information
1235#[derive(Debug, Clone)]
1236pub struct ContextManagerInfo {
1237    pub context_type: ContextManagerType,
1238    pub usage_pattern: ContextUsagePattern,
1239    pub resource_management: ResourceManagementQuality,
1240    pub error_handling: ContextErrorHandling,
1241    pub is_async: bool,
1242    pub nested_level: usize,
1243    pub best_practices_followed: bool,
1244}
1245
1246/// Context manager types
1247#[derive(Debug, Clone)]
1248pub enum ContextManagerType {
1249    BuiltInFileManager,   // open() with statement
1250    CustomContextManager, // Custom __enter__/__exit__
1251    ContextlibManager,    // @contextmanager decorator
1252    AsyncContextManager,  // async __aenter__/__aexit__
1253    DatabaseConnection,   // DB connection managers
1254    LockManager,          // Threading/asyncio locks
1255    TemporaryResource,    // tempfile, temporary dirs
1256    ExceptionSuppression, // contextlib.suppress
1257}
1258
1259/// Context usage patterns
1260#[derive(Debug, Clone)]
1261pub enum ContextUsagePattern {
1262    SingleContext,      // Single with statement
1263    MultipleContexts,   // Multiple with variables
1264    NestedContexts,     // Nested with statements
1265    AsyncContext,       // async with
1266    ConditionalContext, // with in conditional blocks
1267    LoopContext,        // with in loops
1268}
1269
1270/// Resource management quality
1271#[derive(Debug, Clone)]
1272pub enum ResourceManagementQuality {
1273    Excellent, // Proper resource cleanup, error handling
1274    Good,      // Good resource management with minor issues
1275    Adequate,  // Basic resource management
1276    Poor,      // Resource leaks possible
1277    Dangerous, // Major resource management issues
1278}
1279
1280/// Context error handling
1281#[derive(Debug, Clone)]
1282pub enum ContextErrorHandling {
1283    Comprehensive, // Full exception handling
1284    Basic,         // Basic error handling
1285    Minimal,       // Minimal error handling
1286    None,          // No error handling
1287}
1288
1289/// F-string analysis information
1290#[derive(Debug, Clone)]
1291pub struct FStringInfo {
1292    pub expression: String,
1293    pub complexity: FStringComplexity,
1294    pub features_used: Vec<FStringFeature>,
1295    pub performance_impact: PerformanceImpact,
1296    pub formatting_quality: FormattingQuality,
1297    pub readability_score: i32,
1298}
1299
1300/// F-string complexity levels
1301#[derive(Debug, Clone, PartialEq)]
1302pub enum FStringComplexity {
1303    Simple,   // Basic variable interpolation
1304    Moderate, // Simple expressions and formatting
1305    Complex,  // Complex expressions, nested calls
1306    Advanced, // Very complex expressions, performance concerns
1307}
1308
1309/// F-string features
1310#[derive(Debug, Clone, PartialEq)]
1311pub enum FStringFeature {
1312    BasicInterpolation,   // f"{variable}"
1313    ExpressionEvaluation, // f"{expression()}"
1314    FormatSpecifiers,     // f"{value:.2f}"
1315    ConversionFlags,      // f"{value!r}"
1316    NestedFormatting,     // f"{f'{inner}'}"
1317    MultilineString,      // Multiline f-strings
1318    RawFString,           // rf"string"
1319    ComplexExpressions,   // f"{complex.expression}"
1320}
1321
1322/// Performance impact assessment
1323#[derive(Debug, Clone)]
1324pub enum PerformanceImpact {
1325    Positive, // Better performance than alternatives
1326    Neutral,  // Similar performance
1327    Negative, // Worse performance
1328    Critical, // Significantly worse performance
1329}
1330
1331/// Formatting quality assessment
1332#[derive(Debug, Clone)]
1333pub enum FormattingQuality {
1334    Excellent,  // Clear, readable, appropriate formatting
1335    Good,       // Good formatting with minor issues
1336    Adequate,   // Basic formatting, functional
1337    Poor,       // Poor formatting choices
1338    Unreadable, // Very poor formatting, hard to read
1339}
1340
1341/// Pattern matching analysis (Python 3.10+)
1342#[derive(Debug, Clone)]
1343pub struct PatternMatchingInfo {
1344    pub match_statement: String,
1345    pub pattern_types: Vec<PatternType>,
1346    pub complexity: PatternComplexity,
1347    pub has_guards: bool,
1348    pub is_exhaustive: bool,
1349    pub performance_characteristics: MatchPerformance,
1350    pub best_practices_score: i32,
1351}
1352
1353/// Pattern types in match statements
1354#[derive(Debug, Clone)]
1355pub enum PatternType {
1356    LiteralPattern,  // case 42:
1357    VariablePattern, // case x:
1358    WildcardPattern, // case _:
1359    ValuePattern,    // case Color.RED:
1360    GroupPattern,    // case (x, y):
1361    SequencePattern, // case [x, *rest]:
1362    MappingPattern,  // case {"key": value}:
1363    ClassPattern,    // case Point(x, y):
1364    OrPattern,       // case x | y:
1365    AsPattern,       // case x as y:
1366    GuardedPattern,  // case x if condition:
1367}
1368
1369/// Pattern matching complexity
1370#[derive(Debug, Clone)]
1371pub enum PatternComplexity {
1372    Simple,   // Basic literal/variable patterns
1373    Moderate, // Some structured patterns
1374    Complex,  // Complex nested patterns
1375    Advanced, // Very complex patterns with guards
1376}
1377
1378/// Match statement performance characteristics
1379#[derive(Debug, Clone)]
1380pub enum MatchPerformance {
1381    Optimal,  // Efficient pattern matching
1382    Good,     // Good performance
1383    Fair,     // Adequate performance
1384    Poor,     // Inefficient patterns
1385    Critical, // Very poor performance
1386}
1387
1388/// Generator analysis information
1389#[derive(Debug, Clone)]
1390pub struct GeneratorInfo {
1391    pub generator_type: GeneratorType,
1392    pub usage_pattern: GeneratorUsagePattern,
1393    pub memory_efficiency: MemoryEfficiency,
1394    pub complexity: GeneratorComplexity,
1395    pub is_async: bool,
1396    pub yield_analysis: YieldAnalysis,
1397    pub optimization_opportunities: Vec<String>,
1398}
1399
1400/// Generator types
1401#[derive(Debug, Clone)]
1402pub enum GeneratorType {
1403    GeneratorFunction,   // def func(): yield
1404    GeneratorExpression, // (x for x in iterable)
1405    AsyncGenerator,      // async def func(): yield
1406    Comprehension,       // List/dict/set comprehensions
1407    IteratorProtocol,    // __iter__, __next__
1408}
1409
1410/// Generator usage patterns
1411#[derive(Debug, Clone)]
1412pub enum GeneratorUsagePattern {
1413    SimpleIteration,    // Basic iteration
1414    DataTransformation, // Data processing pipeline
1415    LazyEvaluation,     // Lazy computation
1416    InfiniteSequence,   // Infinite generators
1417    Coroutine,          // Coroutine patterns
1418    Pipeline,           // Chained generators
1419}
1420
1421/// Memory efficiency assessment
1422#[derive(Debug, Clone)]
1423pub enum MemoryEfficiency {
1424    Excellent, // Very memory efficient
1425    Good,      // Good memory usage
1426    Adequate,  // Acceptable memory usage
1427    Poor,      // Inefficient memory usage
1428    Critical,  // Very poor memory usage
1429}
1430
1431/// Generator complexity
1432#[derive(Debug, Clone)]
1433pub enum GeneratorComplexity {
1434    Simple,   // Basic yield statements
1435    Moderate, // Some control flow
1436    Complex,  // Complex logic, multiple yields
1437    Advanced, // Very complex generators
1438}
1439
1440/// Yield analysis
1441#[derive(Debug, Clone)]
1442pub struct YieldAnalysis {
1443    pub yield_count: usize,
1444    pub has_yield_from: bool,
1445    pub has_send_values: bool,
1446    pub has_throw_values: bool,
1447    pub has_close_handling: bool,
1448}
1449
1450/// Modern decorator analysis
1451#[derive(Debug, Clone)]
1452pub struct ModernDecoratorInfo {
1453    pub decorator_name: String,
1454    pub decorator_category: DecoratorCategory,
1455    pub usage_pattern: DecoratorUsagePattern,
1456    pub complexity: DecoratorComplexity,
1457    pub is_factory: bool,
1458    pub is_async: bool,
1459    pub parameters: Vec<String>,
1460    pub best_practices_score: i32,
1461}
1462
1463/// Decorator categories
1464#[derive(Debug, Clone)]
1465pub enum DecoratorCategory {
1466    BuiltIn,            // @property, @staticmethod, @classmethod
1467    FunctoolsDecorator, // @wraps, @singledispatch, @cache
1468    AsyncDecorator,     // Async-related decorators
1469    DataValidation,     // Pydantic, dataclass validators
1470    WebFramework,       // Flask, FastAPI decorators
1471    Testing,            // pytest, unittest decorators
1472    Performance,        // @lru_cache, timing decorators
1473    Custom,             // Custom user decorators
1474}
1475
1476/// Decorator usage patterns
1477#[derive(Debug, Clone)]
1478pub enum DecoratorUsagePattern {
1479    SingleDecorator,        // Single decorator
1480    StackedDecorators,      // Multiple decorators
1481    ParameterizedDecorator, // Decorator with parameters
1482    ConditionalDecorator,   // Conditional application
1483    DynamicDecorator,       // Runtime decoration
1484}
1485
1486/// Decorator complexity
1487#[derive(Debug, Clone)]
1488pub enum DecoratorComplexity {
1489    Simple,   // Basic decorators
1490    Moderate, // Parameterized decorators
1491    Complex,  // Complex decorator logic
1492    Advanced, // Very complex decorator patterns
1493}
1494
1495/// Modern syntax features
1496#[derive(Debug, Clone)]
1497pub struct ModernSyntaxInfo {
1498    pub feature_type: ModernSyntaxType,
1499    pub python_version: String,
1500    pub usage_count: usize,
1501    pub complexity: SyntaxComplexity,
1502    pub best_practices_followed: bool,
1503    pub migration_suggestions: Vec<String>,
1504}
1505
1506/// Modern syntax types
1507#[derive(Debug, Clone, PartialEq)]
1508pub enum ModernSyntaxType {
1509    WalrusOperator,       // := (Python 3.8+)
1510    PositionalOnlyParams, // def func(a, /, b) (Python 3.8+)
1511    TypeUnionOperator,    // int | str (Python 3.10+)
1512    ExceptionGroups,      // except* (Python 3.11+)
1513    GenericTypeHints,     // list[int] (Python 3.9+)
1514    StringPrefixChaining, // rf"string" (Python 3.6+)
1515    DictUnionOperator,    // dict1 | dict2 (Python 3.9+)
1516    RemovePrefix,         // str.removeprefix() (Python 3.9+)
1517    ContextVars,          // contextvars (Python 3.7+)
1518}
1519
1520/// Syntax complexity
1521#[derive(Debug, Clone)]
1522pub enum SyntaxComplexity {
1523    Simple,   // Basic usage
1524    Moderate, // Standard usage
1525    Complex,  // Advanced usage
1526    Expert,   // Expert-level usage
1527}
1528
1529/// Feature complexity assessment
1530#[derive(Debug, Clone)]
1531pub enum FeatureComplexity {
1532    Simple,   // Basic feature usage
1533    Moderate, // Standard feature usage
1534    Complex,  // Advanced feature usage
1535    Expert,   // Expert-level feature usage
1536}
1537
1538/// Pattern for modern feature detection
1539#[derive(Debug, Clone)]
1540struct ModernFeaturePattern {
1541    name: String,
1542    pattern: Regex,
1543    #[allow(dead_code)] // Will be used for feature categorization
1544    feature_type: String,
1545    python_version: String,
1546    complexity: FeatureComplexity,
1547}
1548
1549/// Python-specific analyzer
1550pub struct PythonAnalyzer {
1551    decorator_patterns: HashMap<String, Vec<DecoratorPattern>>,
1552    metaclass_patterns: HashMap<String, Vec<MetaclassPattern>>,
1553    security_patterns: HashMap<String, Vec<SecurityPattern>>,
1554    performance_patterns: HashMap<String, Vec<PerformancePattern>>,
1555    framework_patterns: HashMap<String, Vec<FrameworkPattern>>,
1556    type_hint_patterns: HashMap<String, Vec<TypeHintPattern>>,
1557    async_patterns: HashMap<String, Vec<AsyncPattern>>,
1558    dependency_patterns: HashMap<String, Vec<DependencyPattern>>,
1559    modern_feature_patterns: HashMap<String, Vec<ModernFeaturePattern>>,
1560}
1561
1562#[derive(Debug, Clone)]
1563struct DecoratorPattern {
1564    name: String,
1565    pattern: Regex,
1566    framework: Option<String>,
1567    effects: Vec<String>,
1568    is_factory: bool,
1569}
1570
1571#[derive(Debug, Clone)]
1572struct MetaclassPattern {
1573    #[allow(dead_code)] // Will be used for pattern identification
1574    name: String,
1575    pattern: Regex,
1576    impact: String,
1577}
1578
1579#[derive(Debug, Clone)]
1580struct SecurityPattern {
1581    #[allow(dead_code)] // Will be used for pattern identification
1582    name: String,
1583    pattern: Regex,
1584    vulnerability_type: VulnerabilityType,
1585    severity: VulnerabilitySeverity,
1586    description: String,
1587}
1588
1589#[derive(Debug, Clone)]
1590struct PerformancePattern {
1591    #[allow(dead_code)] // Will be used for pattern identification
1592    name: String,
1593    pattern: Regex,
1594    optimization_type: OptimizationType,
1595    impact_level: ImpactLevel,
1596    description: String,
1597}
1598
1599#[derive(Debug, Clone)]
1600struct FrameworkPattern {
1601    #[allow(dead_code)] // Will be used for pattern identification
1602    name: String,
1603    pattern: Regex,
1604    framework: String,
1605    features: Vec<String>,
1606    confidence: f32,
1607}
1608
1609impl PythonAnalyzer {
1610    pub fn new() -> Self {
1611        let mut analyzer = Self {
1612            decorator_patterns: HashMap::new(),
1613            metaclass_patterns: HashMap::new(),
1614            security_patterns: HashMap::new(),
1615            performance_patterns: HashMap::new(),
1616            framework_patterns: HashMap::new(),
1617            type_hint_patterns: HashMap::new(),
1618            async_patterns: HashMap::new(),
1619            dependency_patterns: HashMap::new(),
1620            modern_feature_patterns: HashMap::new(),
1621        };
1622        analyzer.initialize_patterns();
1623        analyzer
1624    }
1625
1626    fn initialize_patterns(&mut self) {
1627        // Framework decorators
1628        let framework_decorators = vec![
1629            DecoratorPattern {
1630                name: "Flask Route".to_string(),
1631                pattern: Regex::new(r"@app\.route\s*\([^)]*\)").unwrap(),
1632                framework: Some("Flask".to_string()),
1633                effects: vec!["URL routing".to_string(), "HTTP method binding".to_string()],
1634                is_factory: true,
1635            },
1636            DecoratorPattern {
1637                name: "Django View".to_string(),
1638                pattern: Regex::new(r"@(?:login_required|permission_required|csrf_exempt)")
1639                    .unwrap(),
1640                framework: Some("Django".to_string()),
1641                effects: vec!["Authentication".to_string(), "Authorization".to_string()],
1642                is_factory: false,
1643            },
1644            DecoratorPattern {
1645                name: "FastAPI Route".to_string(),
1646                pattern: Regex::new(r"@app\.(?:get|post|put|delete|patch)\s*\([^)]*\)").unwrap(),
1647                framework: Some("FastAPI".to_string()),
1648                effects: vec!["API endpoint".to_string(), "Request validation".to_string()],
1649                is_factory: true,
1650            },
1651            DecoratorPattern {
1652                name: "Pytest Fixture".to_string(),
1653                pattern: Regex::new(r"@pytest\.fixture\s*(?:\([^)]*\))?").unwrap(),
1654                framework: Some("pytest".to_string()),
1655                effects: vec!["Test setup".to_string(), "Dependency injection".to_string()],
1656                is_factory: true,
1657            },
1658            DecoratorPattern {
1659                name: "SQLAlchemy Event".to_string(),
1660                pattern: Regex::new(r"@event\.listens_for\s*\([^)]*\)").unwrap(),
1661                framework: Some("SQLAlchemy".to_string()),
1662                effects: vec!["Database event handling".to_string()],
1663                is_factory: true,
1664            },
1665            DecoratorPattern {
1666                name: "Celery Task".to_string(),
1667                pattern: Regex::new(r"@(?:celery\.)?task\s*(?:\([^)]*\))?").unwrap(),
1668                framework: Some("Celery".to_string()),
1669                effects: vec![
1670                    "Async task execution".to_string(),
1671                    "Queue processing".to_string(),
1672                ],
1673                is_factory: true,
1674            },
1675        ];
1676        self.decorator_patterns
1677            .insert("framework".to_string(), framework_decorators);
1678
1679        // Pattern decorators
1680        let pattern_decorators = vec![
1681            DecoratorPattern {
1682                name: "Caching Decorator".to_string(),
1683                pattern: Regex::new(r"@(?:cache|lru_cache|memoize)").unwrap(),
1684                framework: None,
1685                effects: vec![
1686                    "Result caching".to_string(),
1687                    "Performance optimization".to_string(),
1688                ],
1689                is_factory: false,
1690            },
1691            DecoratorPattern {
1692                name: "Validation Decorator".to_string(),
1693                pattern: Regex::new(r"@(?:validate|validator|check)").unwrap(),
1694                framework: None,
1695                effects: vec!["Input validation".to_string(), "Type checking".to_string()],
1696                is_factory: false,
1697            },
1698            DecoratorPattern {
1699                name: "Authorization Decorator".to_string(),
1700                pattern: Regex::new(r"@(?:requires_auth|authorized|permission)").unwrap(),
1701                framework: None,
1702                effects: vec![
1703                    "Access control".to_string(),
1704                    "Security enforcement".to_string(),
1705                ],
1706                is_factory: false,
1707            },
1708            DecoratorPattern {
1709                name: "Logging Decorator".to_string(),
1710                pattern: Regex::new(r"@(?:log|trace|audit)").unwrap(),
1711                framework: None,
1712                effects: vec![
1713                    "Function logging".to_string(),
1714                    "Execution tracing".to_string(),
1715                ],
1716                is_factory: false,
1717            },
1718        ];
1719        self.decorator_patterns
1720            .insert("patterns".to_string(), pattern_decorators);
1721
1722        // Metaclass patterns
1723        let metaclass_patterns = vec![
1724            MetaclassPattern {
1725                name: "Registry Metaclass".to_string(),
1726                pattern: Regex::new(r"class\s+\w+\s*\([^)]*metaclass\s*=\s*\w*Registry\w*")
1727                    .unwrap(),
1728                impact: "Automatic class registration".to_string(),
1729            },
1730            MetaclassPattern {
1731                name: "Singleton Metaclass".to_string(),
1732                pattern: Regex::new(r"class\s+\w+\s*\([^)]*metaclass\s*=\s*\w*Singleton\w*")
1733                    .unwrap(),
1734                impact: "Single instance enforcement".to_string(),
1735            },
1736            MetaclassPattern {
1737                name: "Attribute Injection Metaclass".to_string(),
1738                pattern: Regex::new(r"class\s+\w+\s*\([^)]*metaclass\s*=\s*\w*Inject\w*").unwrap(),
1739                impact: "Dynamic attribute injection".to_string(),
1740            },
1741            MetaclassPattern {
1742                name: "ORM Metaclass".to_string(),
1743                pattern: Regex::new(r"class\s+\w+\s*\([^)]*metaclass\s*=\s*\w*Model\w*").unwrap(),
1744                impact: "Database mapping and validation".to_string(),
1745            },
1746        ];
1747        self.metaclass_patterns
1748            .insert("common".to_string(), metaclass_patterns);
1749
1750        // Security patterns
1751        let security_patterns = vec![
1752            SecurityPattern {
1753                name: "SQL Injection Risk".to_string(),
1754                pattern: Regex::new(r#"(?:execute|raw)\s*\(\s*[f"'].*%.*[f"']"#).unwrap(),
1755                vulnerability_type: VulnerabilityType::SqlInjection,
1756                severity: VulnerabilitySeverity::High,
1757                description: "Potential SQL injection via string formatting".to_string(),
1758            },
1759            SecurityPattern {
1760                name: "Command Injection Risk".to_string(),
1761                pattern: Regex::new(r"(?:subprocess|os\.system)\s*\(.*(?:input|request)").unwrap(),
1762                vulnerability_type: VulnerabilityType::CommandInjection,
1763                severity: VulnerabilitySeverity::Critical,
1764                description: "Command injection via user input".to_string(),
1765            },
1766            SecurityPattern {
1767                name: "Unsafe Pickle Usage".to_string(),
1768                pattern: Regex::new(r"pickle\.loads?\s*\(").unwrap(),
1769                vulnerability_type: VulnerabilityType::DeserializationAttack,
1770                severity: VulnerabilitySeverity::High,
1771                description: "Unsafe pickle deserialization".to_string(),
1772            },
1773            SecurityPattern {
1774                name: "Hardcoded Secrets".to_string(),
1775                pattern: Regex::new(r#"(?:password|secret|key|token)\s*=\s*[f"'][^"']*[f"']"#)
1776                    .unwrap(),
1777                vulnerability_type: VulnerabilityType::HardcodedSecrets,
1778                severity: VulnerabilitySeverity::Medium,
1779                description: "Hardcoded credentials in source code".to_string(),
1780            },
1781        ];
1782        self.security_patterns
1783            .insert("vulnerabilities".to_string(), security_patterns);
1784
1785        // Performance patterns
1786        let performance_patterns = vec![
1787            PerformancePattern {
1788                name: "List Comprehension Optimization".to_string(),
1789                pattern: Regex::new(r"\[.*for.*in.*\]").unwrap(),
1790                optimization_type: OptimizationType::ListComprehension,
1791                impact_level: ImpactLevel::Medium,
1792                description: "Efficient list comprehension usage".to_string(),
1793            },
1794            PerformancePattern {
1795                name: "Generator Usage".to_string(),
1796                pattern: Regex::new(r"\(.*for.*in.*\)").unwrap(),
1797                optimization_type: OptimizationType::GeneratorUsage,
1798                impact_level: ImpactLevel::High,
1799                description: "Memory-efficient generator expression".to_string(),
1800            },
1801            PerformancePattern {
1802                name: "Caching Implementation".to_string(),
1803                pattern: Regex::new(r"@(?:lru_cache|cache)").unwrap(),
1804                optimization_type: OptimizationType::CachingImplementation,
1805                impact_level: ImpactLevel::High,
1806                description: "Function result caching".to_string(),
1807            },
1808            PerformancePattern {
1809                name: "Async/Await Usage".to_string(),
1810                pattern: Regex::new(r"async\s+def|await\s+").unwrap(),
1811                optimization_type: OptimizationType::AsyncAwaitUsage,
1812                impact_level: ImpactLevel::High,
1813                description: "Asynchronous programming patterns".to_string(),
1814            },
1815        ];
1816        self.performance_patterns
1817            .insert("optimizations".to_string(), performance_patterns);
1818
1819        // Framework patterns
1820        let framework_patterns = vec![
1821            FrameworkPattern {
1822                name: "Django Framework".to_string(),
1823                pattern: Regex::new(r"from\s+django|import\s+django").unwrap(),
1824                framework: "Django".to_string(),
1825                features: vec![
1826                    "Models".to_string(),
1827                    "Views".to_string(),
1828                    "Templates".to_string(),
1829                ],
1830                confidence: 0.9,
1831            },
1832            FrameworkPattern {
1833                name: "Flask Framework".to_string(),
1834                pattern: Regex::new(r"from\s+flask|import\s+flask").unwrap(),
1835                framework: "Flask".to_string(),
1836                features: vec![
1837                    "Routes".to_string(),
1838                    "Blueprints".to_string(),
1839                    "Templates".to_string(),
1840                ],
1841                confidence: 0.9,
1842            },
1843            FrameworkPattern {
1844                name: "FastAPI Framework".to_string(),
1845                pattern: Regex::new(r"from\s+fastapi|import\s+fastapi").unwrap(),
1846                framework: "FastAPI".to_string(),
1847                features: vec![
1848                    "API Routes".to_string(),
1849                    "Dependency Injection".to_string(),
1850                    "Validation".to_string(),
1851                ],
1852                confidence: 0.9,
1853            },
1854            FrameworkPattern {
1855                name: "Pytest Framework".to_string(),
1856                pattern: Regex::new(r"import\s+pytest|@pytest").unwrap(),
1857                framework: "Pytest".to_string(),
1858                features: vec![
1859                    "Fixtures".to_string(),
1860                    "Parametrization".to_string(),
1861                    "Markers".to_string(),
1862                ],
1863                confidence: 0.8,
1864            },
1865        ];
1866        self.framework_patterns
1867            .insert("web_frameworks".to_string(), framework_patterns);
1868
1869        // Type hint patterns
1870        let type_hint_patterns = vec![
1871            TypeHintPattern {
1872                name: "Union Type".to_string(),
1873                pattern: Regex::new(r"Union\[([^]]+)\]").unwrap(),
1874                hint_type: "union".to_string(),
1875                complexity: TypeComplexity::Moderate,
1876                python_version: "3.5+".to_string(),
1877            },
1878            TypeHintPattern {
1879                name: "Union Type (PEP 604)".to_string(),
1880                pattern: Regex::new(r"(\w+)\s*\|\s*(\w+)").unwrap(),
1881                hint_type: "union_new".to_string(),
1882                complexity: TypeComplexity::Moderate,
1883                python_version: "3.10+".to_string(),
1884            },
1885            TypeHintPattern {
1886                name: "Optional Type".to_string(),
1887                pattern: Regex::new(r"Optional\[([^]]+)\]").unwrap(),
1888                hint_type: "optional".to_string(),
1889                complexity: TypeComplexity::Moderate,
1890                python_version: "3.5+".to_string(),
1891            },
1892            TypeHintPattern {
1893                name: "Generic List".to_string(),
1894                pattern: Regex::new(r"List\[([^]]+)\]").unwrap(),
1895                hint_type: "generic_list".to_string(),
1896                complexity: TypeComplexity::Complex,
1897                python_version: "3.5+".to_string(),
1898            },
1899            TypeHintPattern {
1900                name: "Generic Dict".to_string(),
1901                pattern: Regex::new(r"Dict\[([^]]+),\s*([^]]+)\]").unwrap(),
1902                hint_type: "generic_dict".to_string(),
1903                complexity: TypeComplexity::Complex,
1904                python_version: "3.5+".to_string(),
1905            },
1906            TypeHintPattern {
1907                name: "Callable Type".to_string(),
1908                pattern: Regex::new(r"Callable\[\[([^]]*)\],\s*([^]]+)\]").unwrap(),
1909                hint_type: "callable".to_string(),
1910                complexity: TypeComplexity::Advanced,
1911                python_version: "3.5+".to_string(),
1912            },
1913            TypeHintPattern {
1914                name: "TypeVar".to_string(),
1915                pattern: Regex::new(r#"TypeVar\s*\(\s*["'](\w+)["']"#).unwrap(),
1916                hint_type: "typevar".to_string(),
1917                complexity: TypeComplexity::Advanced,
1918                python_version: "3.5+".to_string(),
1919            },
1920            TypeHintPattern {
1921                name: "Protocol".to_string(),
1922                pattern: Regex::new(r"class\s+\w+\s*\([^)]*Protocol[^)]*\)").unwrap(),
1923                hint_type: "protocol".to_string(),
1924                complexity: TypeComplexity::Advanced,
1925                python_version: "3.8+".to_string(),
1926            },
1927            TypeHintPattern {
1928                name: "Literal Type".to_string(),
1929                pattern: Regex::new(r"Literal\[([^]]+)\]").unwrap(),
1930                hint_type: "literal".to_string(),
1931                complexity: TypeComplexity::Moderate,
1932                python_version: "3.8+".to_string(),
1933            },
1934            TypeHintPattern {
1935                name: "Final Type".to_string(),
1936                pattern: Regex::new(r"Final\[([^]]+)\]").unwrap(),
1937                hint_type: "final".to_string(),
1938                complexity: TypeComplexity::Moderate,
1939                python_version: "3.8+".to_string(),
1940            },
1941            TypeHintPattern {
1942                name: "TypedDict".to_string(),
1943                pattern: Regex::new(r"class\s+(\w+)\s*\(\s*TypedDict\s*\)").unwrap(),
1944                hint_type: "typeddict".to_string(),
1945                complexity: TypeComplexity::Complex,
1946                python_version: "3.8+".to_string(),
1947            },
1948            TypeHintPattern {
1949                name: "Generic Alias (Python 3.9+)".to_string(),
1950                pattern: Regex::new(r"\b(list|dict|set|tuple)\s*\[([^]]+)\]").unwrap(),
1951                hint_type: "generic_alias".to_string(),
1952                complexity: TypeComplexity::Simple,
1953                python_version: "3.9+".to_string(),
1954            },
1955        ];
1956        self.type_hint_patterns
1957            .insert("type_hints".to_string(), type_hint_patterns);
1958
1959        // Async/await patterns
1960        let async_patterns = vec![
1961            AsyncPattern {
1962                name: "Async Function".to_string(),
1963                pattern: Regex::new(r"async\s+def\s+(\w+)").unwrap(),
1964                pattern_type: "function".to_string(),
1965                performance_impact: AsyncPerformanceImpact::Positive,
1966            },
1967            AsyncPattern {
1968                name: "Async Generator".to_string(),
1969                pattern: Regex::new(r"async\s+def\s+\w+.*yield").unwrap(),
1970                pattern_type: "generator".to_string(),
1971                performance_impact: AsyncPerformanceImpact::Positive,
1972            },
1973            AsyncPattern {
1974                name: "Async Context Manager".to_string(),
1975                pattern: Regex::new(r"async\s+def\s+__aenter__|async\s+def\s+__aexit__").unwrap(),
1976                pattern_type: "context_manager".to_string(),
1977                performance_impact: AsyncPerformanceImpact::Positive,
1978            },
1979            AsyncPattern {
1980                name: "Async Iterator".to_string(),
1981                pattern: Regex::new(r"async\s+def\s+__aiter__|async\s+def\s+__anext__").unwrap(),
1982                pattern_type: "iterator".to_string(),
1983                performance_impact: AsyncPerformanceImpact::Positive,
1984            },
1985            AsyncPattern {
1986                name: "Await Expression".to_string(),
1987                pattern: Regex::new(r"await\s+(\w+[\w\.\(\)]*)+").unwrap(),
1988                pattern_type: "await".to_string(),
1989                performance_impact: AsyncPerformanceImpact::Neutral,
1990            },
1991            AsyncPattern {
1992                name: "Asyncio Gather".to_string(),
1993                pattern: Regex::new(r"asyncio\.gather\s*\(").unwrap(),
1994                pattern_type: "concurrency".to_string(),
1995                performance_impact: AsyncPerformanceImpact::Positive,
1996            },
1997            AsyncPattern {
1998                name: "Asyncio Wait".to_string(),
1999                pattern: Regex::new(r"asyncio\.wait\s*\(").unwrap(),
2000                pattern_type: "concurrency".to_string(),
2001                performance_impact: AsyncPerformanceImpact::Positive,
2002            },
2003            AsyncPattern {
2004                name: "Asyncio Queue".to_string(),
2005                pattern: Regex::new(r"asyncio\.Queue\s*\(").unwrap(),
2006                pattern_type: "concurrency".to_string(),
2007                performance_impact: AsyncPerformanceImpact::Positive,
2008            },
2009            AsyncPattern {
2010                name: "Asyncio Semaphore".to_string(),
2011                pattern: Regex::new(r"asyncio\.Semaphore\s*\(").unwrap(),
2012                pattern_type: "concurrency".to_string(),
2013                performance_impact: AsyncPerformanceImpact::Positive,
2014            },
2015            AsyncPattern {
2016                name: "Asyncio Lock".to_string(),
2017                pattern: Regex::new(r"asyncio\.Lock\s*\(").unwrap(),
2018                pattern_type: "concurrency".to_string(),
2019                performance_impact: AsyncPerformanceImpact::Positive,
2020            },
2021            AsyncPattern {
2022                name: "TaskGroup".to_string(),
2023                pattern: Regex::new(r"asyncio\.TaskGroup\s*\(").unwrap(),
2024                pattern_type: "concurrency".to_string(),
2025                performance_impact: AsyncPerformanceImpact::Positive,
2026            },
2027            AsyncPattern {
2028                name: "Asyncio Timeout".to_string(),
2029                pattern: Regex::new(r"asyncio\.timeout\s*\(").unwrap(),
2030                pattern_type: "timeout".to_string(),
2031                performance_impact: AsyncPerformanceImpact::Positive,
2032            },
2033            AsyncPattern {
2034                name: "Async With Statement".to_string(),
2035                pattern: Regex::new(r"async\s+with\s+").unwrap(),
2036                pattern_type: "context_manager".to_string(),
2037                performance_impact: AsyncPerformanceImpact::Positive,
2038            },
2039            AsyncPattern {
2040                name: "Async For Loop".to_string(),
2041                pattern: Regex::new(r"async\s+for\s+").unwrap(),
2042                pattern_type: "iterator".to_string(),
2043                performance_impact: AsyncPerformanceImpact::Positive,
2044            },
2045            AsyncPattern {
2046                name: "Blocking IO in Async".to_string(),
2047                pattern: Regex::new(
2048                    r"(?:open|input|print)\s*\(.*\).*await|await.*(?:open|input|print)\s*\(",
2049                )
2050                .unwrap(),
2051                pattern_type: "performance_issue".to_string(),
2052                performance_impact: AsyncPerformanceImpact::Critical,
2053            },
2054        ];
2055        self.async_patterns
2056            .insert("functions".to_string(), async_patterns);
2057
2058        let concurrency_patterns = vec![
2059            AsyncPattern {
2060                name: "Concurrent Futures".to_string(),
2061                pattern: Regex::new(r"concurrent\.futures").unwrap(),
2062                pattern_type: "concurrency".to_string(),
2063                performance_impact: AsyncPerformanceImpact::Positive,
2064            },
2065            AsyncPattern {
2066                name: "Asyncio Event".to_string(),
2067                pattern: Regex::new(r"asyncio\.Event\s*\(").unwrap(),
2068                pattern_type: "concurrency".to_string(),
2069                performance_impact: AsyncPerformanceImpact::Positive,
2070            },
2071            AsyncPattern {
2072                name: "Asyncio Condition".to_string(),
2073                pattern: Regex::new(r"asyncio\.Condition\s*\(").unwrap(),
2074                pattern_type: "concurrency".to_string(),
2075                performance_impact: AsyncPerformanceImpact::Positive,
2076            },
2077        ];
2078        self.async_patterns
2079            .insert("concurrency".to_string(), concurrency_patterns);
2080
2081        let modern_async_patterns = vec![
2082            AsyncPattern {
2083                name: "Asyncio Run".to_string(),
2084                pattern: Regex::new(r"asyncio\.run\s*\(").unwrap(),
2085                pattern_type: "modern".to_string(),
2086                performance_impact: AsyncPerformanceImpact::Positive,
2087            },
2088            AsyncPattern {
2089                name: "Context Variables".to_string(),
2090                pattern: Regex::new(r"contextvars\.ContextVar").unwrap(),
2091                pattern_type: "modern".to_string(),
2092                performance_impact: AsyncPerformanceImpact::Positive,
2093            },
2094            AsyncPattern {
2095                name: "Async Comprehension".to_string(),
2096                pattern: Regex::new(r"\[.*async\s+for.*\]|\{.*async\s+for.*\}").unwrap(),
2097                pattern_type: "modern".to_string(),
2098                performance_impact: AsyncPerformanceImpact::Positive,
2099            },
2100        ];
2101        self.async_patterns
2102            .insert("modern".to_string(), modern_async_patterns);
2103
2104        // Dependency analysis patterns
2105        let requirements_patterns = vec![
2106            DependencyPattern {
2107                name: "Requirements.txt".to_string(),
2108                pattern: Regex::new(r"(?m)^([a-zA-Z0-9_-]+)([><=!~]+)?([0-9.]+)?").unwrap(),
2109                file_type: RequirementsFileType::RequirementsTxt,
2110                extraction_method: "line_by_line".to_string(),
2111            },
2112            DependencyPattern {
2113                name: "Pyproject.toml Dependencies".to_string(),
2114                pattern: Regex::new(r#"dependencies\s*=\s*\[(.*?)\]"#).unwrap(),
2115                file_type: RequirementsFileType::PyprojectToml,
2116                extraction_method: "toml_array".to_string(),
2117            },
2118            DependencyPattern {
2119                name: "Setup.py Install Requires".to_string(),
2120                pattern: Regex::new(r"install_requires\s*=\s*\[(.*?)\]").unwrap(),
2121                file_type: RequirementsFileType::SetupPy,
2122                extraction_method: "python_list".to_string(),
2123            },
2124            DependencyPattern {
2125                name: "Pipfile Dependencies".to_string(),
2126                pattern: Regex::new(r"\[packages\](.*?)\[").unwrap(),
2127                file_type: RequirementsFileType::Pipfile,
2128                extraction_method: "toml_section".to_string(),
2129            },
2130            DependencyPattern {
2131                name: "Poetry Lock".to_string(),
2132                pattern: Regex::new(r#"name\s*=\s*"([^"]+)""#).unwrap(),
2133                file_type: RequirementsFileType::PoetryLock,
2134                extraction_method: "toml_blocks".to_string(),
2135            },
2136            DependencyPattern {
2137                name: "Conda Environment".to_string(),
2138                pattern: Regex::new(r"dependencies:\s*\n(.*?)(?:\n\w|$)").unwrap(),
2139                file_type: RequirementsFileType::CondaYml,
2140                extraction_method: "yaml_list".to_string(),
2141            },
2142        ];
2143        self.dependency_patterns
2144            .insert("requirements".to_string(), requirements_patterns);
2145
2146        let import_patterns = vec![
2147            DependencyPattern {
2148                name: "Standard Import".to_string(),
2149                pattern: Regex::new(r"(?m)^import\s+([a-zA-Z_][a-zA-Z0-9_.]*)").unwrap(),
2150                file_type: RequirementsFileType::SetupPy, // Python source files
2151                extraction_method: "import_statement".to_string(),
2152            },
2153            DependencyPattern {
2154                name: "From Import".to_string(),
2155                pattern: Regex::new(r"(?m)^from\s+([a-zA-Z_][a-zA-Z0-9_.]*)\s+import").unwrap(),
2156                file_type: RequirementsFileType::SetupPy, // Python source files
2157                extraction_method: "import_statement".to_string(),
2158            },
2159            DependencyPattern {
2160                name: "Star Import".to_string(),
2161                pattern: Regex::new(r"(?m)^from\s+([a-zA-Z_][a-zA-Z0-9_.]*)\s+import\s+\*")
2162                    .unwrap(),
2163                file_type: RequirementsFileType::SetupPy, // Python source files
2164                extraction_method: "import_statement".to_string(),
2165            },
2166            DependencyPattern {
2167                name: "Alias Import".to_string(),
2168                pattern: Regex::new(r"(?m)^import\s+([a-zA-Z_][a-zA-Z0-9_.]*)\s+as\s+").unwrap(),
2169                file_type: RequirementsFileType::SetupPy, // Python source files
2170                extraction_method: "import_statement".to_string(),
2171            },
2172            DependencyPattern {
2173                name: "Relative Import".to_string(),
2174                pattern: Regex::new(r"(?m)^from\s+(\.+)([a-zA-Z_][a-zA-Z0-9_.]*)\s+import")
2175                    .unwrap(),
2176                file_type: RequirementsFileType::SetupPy, // Python source files
2177                extraction_method: "import_statement".to_string(),
2178            },
2179        ];
2180        self.dependency_patterns
2181            .insert("imports".to_string(), import_patterns);
2182
2183        // Modern Python feature patterns
2184        let dataclass_patterns = vec![
2185            ModernFeaturePattern {
2186                name: "Dataclass Decorator".to_string(),
2187                pattern: Regex::new(r"@dataclass").unwrap(),
2188                feature_type: "dataclass".to_string(),
2189                python_version: "3.7+".to_string(),
2190                complexity: FeatureComplexity::Moderate,
2191            },
2192            ModernFeaturePattern {
2193                name: "Pydantic Model".to_string(),
2194                pattern: Regex::new(r"class\s+\w+\(BaseModel\)").unwrap(),
2195                feature_type: "dataclass".to_string(),
2196                python_version: "3.6+".to_string(),
2197                complexity: FeatureComplexity::Complex,
2198            },
2199            ModernFeaturePattern {
2200                name: "Named Tuple".to_string(),
2201                pattern: Regex::new(r"NamedTuple|namedtuple").unwrap(),
2202                feature_type: "dataclass".to_string(),
2203                python_version: "3.6+".to_string(),
2204                complexity: FeatureComplexity::Simple,
2205            },
2206            ModernFeaturePattern {
2207                name: "Slots Usage".to_string(),
2208                pattern: Regex::new(r"__slots__\s*=").unwrap(),
2209                feature_type: "dataclass".to_string(),
2210                python_version: "3.0+".to_string(),
2211                complexity: FeatureComplexity::Moderate,
2212            },
2213        ];
2214        self.modern_feature_patterns
2215            .insert("dataclass".to_string(), dataclass_patterns);
2216
2217        let context_manager_patterns = vec![
2218            ModernFeaturePattern {
2219                name: "With Statement".to_string(),
2220                pattern: Regex::new(r"(?m)^(\s*)with\s+").unwrap(),
2221                feature_type: "context_manager".to_string(),
2222                python_version: "2.5+".to_string(),
2223                complexity: FeatureComplexity::Simple,
2224            },
2225            ModernFeaturePattern {
2226                name: "Async With".to_string(),
2227                pattern: Regex::new(r"(?m)^(\s*)async\s+with\s+").unwrap(),
2228                feature_type: "context_manager".to_string(),
2229                python_version: "3.5+".to_string(),
2230                complexity: FeatureComplexity::Complex,
2231            },
2232            ModernFeaturePattern {
2233                name: "Context Manager Protocol".to_string(),
2234                pattern: Regex::new(r"__enter__|__exit__").unwrap(),
2235                feature_type: "context_manager".to_string(),
2236                python_version: "2.5+".to_string(),
2237                complexity: FeatureComplexity::Complex,
2238            },
2239            ModernFeaturePattern {
2240                name: "Contextlib Manager".to_string(),
2241                pattern: Regex::new(r"@contextmanager").unwrap(),
2242                feature_type: "context_manager".to_string(),
2243                python_version: "2.5+".to_string(),
2244                complexity: FeatureComplexity::Moderate,
2245            },
2246        ];
2247        self.modern_feature_patterns
2248            .insert("context_manager".to_string(), context_manager_patterns);
2249
2250        let fstring_patterns = vec![
2251            ModernFeaturePattern {
2252                name: "F-String Basic".to_string(),
2253                pattern: Regex::new(r#"f["'][^"']*\{[^}]+\}[^"']*["']"#).unwrap(),
2254                feature_type: "fstring".to_string(),
2255                python_version: "3.6+".to_string(),
2256                complexity: FeatureComplexity::Simple,
2257            },
2258            ModernFeaturePattern {
2259                name: "F-String Complex".to_string(),
2260                pattern: Regex::new(r#"f["'][^"']*\{[^}]*\([^)]*\)[^}]*\}[^"']*["']"#).unwrap(),
2261                feature_type: "fstring".to_string(),
2262                python_version: "3.6+".to_string(),
2263                complexity: FeatureComplexity::Complex,
2264            },
2265            ModernFeaturePattern {
2266                name: "Raw F-String".to_string(),
2267                pattern: Regex::new(r#"rf["']|fr["']"#).unwrap(),
2268                feature_type: "fstring".to_string(),
2269                python_version: "3.6+".to_string(),
2270                complexity: FeatureComplexity::Moderate,
2271            },
2272        ];
2273        self.modern_feature_patterns
2274            .insert("fstring".to_string(), fstring_patterns);
2275
2276        let pattern_matching_patterns = vec![
2277            ModernFeaturePattern {
2278                name: "Match Statement".to_string(),
2279                pattern: Regex::new(r"(?m)^(\s*)match\s+").unwrap(),
2280                feature_type: "pattern_matching".to_string(),
2281                python_version: "3.10+".to_string(),
2282                complexity: FeatureComplexity::Complex,
2283            },
2284            ModernFeaturePattern {
2285                name: "Case Pattern".to_string(),
2286                pattern: Regex::new(r"(?m)^(\s*)case\s+").unwrap(),
2287                feature_type: "pattern_matching".to_string(),
2288                python_version: "3.10+".to_string(),
2289                complexity: FeatureComplexity::Complex,
2290            },
2291            ModernFeaturePattern {
2292                name: "Guard Pattern".to_string(),
2293                pattern: Regex::new(r"case\s+.*\s+if\s+").unwrap(),
2294                feature_type: "pattern_matching".to_string(),
2295                python_version: "3.10+".to_string(),
2296                complexity: FeatureComplexity::Expert,
2297            },
2298        ];
2299        self.modern_feature_patterns
2300            .insert("pattern_matching".to_string(), pattern_matching_patterns);
2301
2302        let generator_patterns = vec![
2303            ModernFeaturePattern {
2304                name: "Generator Function".to_string(),
2305                pattern: Regex::new(r"def\s+\w+.*?yield").unwrap(),
2306                feature_type: "generator".to_string(),
2307                python_version: "2.2+".to_string(),
2308                complexity: FeatureComplexity::Moderate,
2309            },
2310            ModernFeaturePattern {
2311                name: "Generator Expression".to_string(),
2312                pattern: Regex::new(r"\([^)]*for\s+\w+\s+in\s+[^)]*\)").unwrap(),
2313                feature_type: "generator".to_string(),
2314                python_version: "2.4+".to_string(),
2315                complexity: FeatureComplexity::Simple,
2316            },
2317            ModernFeaturePattern {
2318                name: "Async Generator".to_string(),
2319                pattern: Regex::new(r"async\s+def\s+\w+.*?yield").unwrap(),
2320                feature_type: "generator".to_string(),
2321                python_version: "3.6+".to_string(),
2322                complexity: FeatureComplexity::Expert,
2323            },
2324            ModernFeaturePattern {
2325                name: "Yield From".to_string(),
2326                pattern: Regex::new(r"yield\s+from\s+").unwrap(),
2327                feature_type: "generator".to_string(),
2328                python_version: "3.3+".to_string(),
2329                complexity: FeatureComplexity::Complex,
2330            },
2331        ];
2332        self.modern_feature_patterns
2333            .insert("generator".to_string(), generator_patterns);
2334
2335        let modern_syntax_patterns = vec![
2336            ModernFeaturePattern {
2337                name: "Walrus Operator".to_string(),
2338                pattern: Regex::new(r":=").unwrap(),
2339                feature_type: "modern_syntax".to_string(),
2340                python_version: "3.8+".to_string(),
2341                complexity: FeatureComplexity::Moderate,
2342            },
2343            ModernFeaturePattern {
2344                name: "Positional Only Parameters".to_string(),
2345                pattern: Regex::new(r"def\s+\w+\([^)]*,\s*/\s*[,)]").unwrap(),
2346                feature_type: "modern_syntax".to_string(),
2347                python_version: "3.8+".to_string(),
2348                complexity: FeatureComplexity::Complex,
2349            },
2350            ModernFeaturePattern {
2351                name: "Union Type Operator".to_string(),
2352                pattern: Regex::new(r"\w+\s*\|\s*\w+").unwrap(),
2353                feature_type: "modern_syntax".to_string(),
2354                python_version: "3.10+".to_string(),
2355                complexity: FeatureComplexity::Moderate,
2356            },
2357            ModernFeaturePattern {
2358                name: "Dictionary Union".to_string(),
2359                pattern: Regex::new(r"\w+\s*\|\s*\{").unwrap(),
2360                feature_type: "modern_syntax".to_string(),
2361                python_version: "3.9+".to_string(),
2362                complexity: FeatureComplexity::Simple,
2363            },
2364            ModernFeaturePattern {
2365                name: "Generic Type Hints".to_string(),
2366                pattern: Regex::new(r"list\[|dict\[|set\[|tuple\[").unwrap(),
2367                feature_type: "modern_syntax".to_string(),
2368                python_version: "3.9+".to_string(),
2369                complexity: FeatureComplexity::Moderate,
2370            },
2371        ];
2372        self.modern_feature_patterns
2373            .insert("modern_syntax".to_string(), modern_syntax_patterns);
2374    }
2375
2376    /// Analyze Python decorators
2377    pub fn analyze_decorators(&self, content: &str) -> Result<Vec<DecoratorInfo>> {
2378        let mut decorators = Vec::new();
2379
2380        for (category, patterns) in &self.decorator_patterns {
2381            for pattern in patterns {
2382                for captures in pattern.pattern.captures_iter(content) {
2383                    let full_match = captures.get(0).unwrap().as_str();
2384
2385                    decorators.push(DecoratorInfo {
2386                        name: pattern.name.clone(),
2387                        decorator_type: category.clone(),
2388                        framework: pattern.framework.clone(),
2389                        effects: pattern.effects.clone(),
2390                        is_factory: pattern.is_factory,
2391                        parameters: self.extract_decorator_parameters(full_match),
2392                    });
2393                }
2394            }
2395        }
2396
2397        Ok(decorators)
2398    }
2399
2400    /// Analyze Python metaclasses
2401    pub fn analyze_metaclasses(&self, content: &str) -> Result<Vec<MetaclassInfo>> {
2402        let mut metaclasses = Vec::new();
2403
2404        for (category, patterns) in &self.metaclass_patterns {
2405            for pattern in patterns {
2406                for captures in pattern.pattern.captures_iter(content) {
2407                    let full_match = captures.get(0).unwrap().as_str();
2408                    let class_name = self.extract_class_name(full_match);
2409
2410                    metaclasses.push(MetaclassInfo {
2411                        name: class_name,
2412                        metaclass_type: category.clone(),
2413                        impact: pattern.impact.clone(),
2414                        attributes_modified: self.find_modified_attributes(content, full_match),
2415                        methods_modified: self.find_modified_methods(content, full_match),
2416                    });
2417                }
2418            }
2419        }
2420
2421        Ok(metaclasses)
2422    }
2423
2424    /// Analyze Python inheritance
2425    pub fn analyze_inheritance(&self, content: &str) -> Result<Vec<InheritanceInfo>> {
2426        let mut inheritance_info = Vec::new();
2427
2428        let class_pattern = Regex::new(r"class\s+(\w+)\s*\(([^)]*)\)").unwrap();
2429
2430        for captures in class_pattern.captures_iter(content) {
2431            let class_name = captures.get(1).unwrap().as_str().to_string();
2432            let bases_str = captures.get(2).unwrap().as_str();
2433
2434            let base_classes = self.parse_base_classes(bases_str);
2435            let mro = self.calculate_mro(&class_name, &base_classes);
2436            let has_diamond = self.detect_diamond_inheritance(&base_classes);
2437            let mixins = self.identify_mixins(&base_classes);
2438            let metaclass = self.extract_metaclass(bases_str);
2439
2440            inheritance_info.push(InheritanceInfo {
2441                class_name,
2442                base_classes,
2443                mro,
2444                has_diamond_inheritance: has_diamond,
2445                mixins,
2446                metaclass,
2447            });
2448        }
2449
2450        Ok(inheritance_info)
2451    }
2452
2453    /// Extract decorator parameters
2454    fn extract_decorator_parameters(&self, decorator: &str) -> Vec<String> {
2455        let param_pattern = Regex::new(r"\(([^)]*)\)").unwrap();
2456
2457        if let Some(captures) = param_pattern.captures(decorator) {
2458            let params_str = captures.get(1).unwrap().as_str();
2459            params_str
2460                .split(',')
2461                .map(|p| p.trim().to_string())
2462                .filter(|p| !p.is_empty())
2463                .collect()
2464        } else {
2465            Vec::new()
2466        }
2467    }
2468
2469    /// Extract class name from class definition
2470    fn extract_class_name(&self, class_def: &str) -> String {
2471        let name_pattern = Regex::new(r"class\s+(\w+)").unwrap();
2472
2473        if let Some(captures) = name_pattern.captures(class_def) {
2474            captures.get(1).unwrap().as_str().to_string()
2475        } else {
2476            "Unknown".to_string()
2477        }
2478    }
2479
2480    /// Find attributes modified by metaclass
2481    fn find_modified_attributes(&self, _content: &str, _class_def: &str) -> Vec<String> {
2482        // Simplified implementation - in practice, this would analyze the metaclass code
2483        vec!["__new__".to_string(), "__init__".to_string()]
2484    }
2485
2486    /// Find methods modified by metaclass
2487    fn find_modified_methods(&self, _content: &str, _class_def: &str) -> Vec<String> {
2488        // Simplified implementation - in practice, this would analyze the metaclass code
2489        vec!["__call__".to_string()]
2490    }
2491
2492    /// Parse base classes from inheritance declaration
2493    fn parse_base_classes(&self, bases_str: &str) -> Vec<String> {
2494        bases_str
2495            .split(',')
2496            .map(|base| {
2497                // Remove metaclass and other keyword arguments
2498                let clean_base = base.split('=').next().unwrap_or(base).trim();
2499                clean_base.to_string()
2500            })
2501            .filter(|base| !base.is_empty() && !base.contains("metaclass"))
2502            .collect()
2503    }
2504
2505    /// Calculate Method Resolution Order (simplified)
2506    fn calculate_mro(&self, class_name: &str, base_classes: &[String]) -> Vec<String> {
2507        let mut mro = vec![class_name.to_string()];
2508        mro.extend(base_classes.iter().cloned());
2509        mro.push("object".to_string());
2510        mro
2511    }
2512
2513    /// Detect diamond inheritance pattern
2514    fn detect_diamond_inheritance(&self, base_classes: &[String]) -> bool {
2515        // Simplified check - in practice, this would build the full inheritance graph
2516        base_classes.len() > 1
2517    }
2518
2519    /// Identify mixin classes
2520    fn identify_mixins(&self, base_classes: &[String]) -> Vec<String> {
2521        base_classes
2522            .iter()
2523            .filter(|base| base.ends_with("Mixin") || base.ends_with("Mix"))
2524            .cloned()
2525            .collect()
2526    }
2527
2528    /// Extract metaclass from base classes
2529    fn extract_metaclass(&self, bases_str: &str) -> Option<String> {
2530        let metaclass_pattern = Regex::new(r"metaclass\s*=\s*(\w+)").unwrap();
2531
2532        metaclass_pattern
2533            .captures(bases_str)
2534            .map(|captures| captures.get(1).unwrap().as_str().to_string())
2535    }
2536
2537    /// Analyze Python security vulnerabilities and features
2538    pub fn analyze_security(&self, content: &str) -> Result<PythonSecurityAssessment> {
2539        let mut vulnerabilities = Vec::new();
2540        let mut security_features = Vec::new();
2541
2542        // Detect vulnerabilities
2543        for patterns in self.security_patterns.values() {
2544            for pattern in patterns {
2545                for captures in pattern.pattern.captures_iter(content) {
2546                    let full_match = captures.get(0).unwrap().as_str();
2547
2548                    vulnerabilities.push(SecurityVulnerability {
2549                        vulnerability_type: pattern.vulnerability_type.clone(),
2550                        severity: pattern.severity.clone(),
2551                        description: pattern.description.clone(),
2552                        location: full_match.to_string(),
2553                        recommendation: self
2554                            .get_security_recommendation(&pattern.vulnerability_type),
2555                    });
2556                }
2557            }
2558        }
2559
2560        // Detect security features
2561        if content.contains("bcrypt") || content.contains("hashlib") {
2562            security_features.push(SecurityFeature {
2563                feature_type: SecurityFeatureType::DataEncryption,
2564                implementation_quality: ImplementationQuality::Good,
2565                description: "Password hashing implementation detected".to_string(),
2566            });
2567        }
2568
2569        if content.contains("@csrf_exempt") || content.contains("CsrfViewMiddleware") {
2570            security_features.push(SecurityFeature {
2571                feature_type: SecurityFeatureType::CsrfProtection,
2572                implementation_quality: ImplementationQuality::Good,
2573                description: "CSRF protection implementation detected".to_string(),
2574            });
2575        }
2576
2577        if content.contains("pydantic") || content.contains("marshmallow") {
2578            security_features.push(SecurityFeature {
2579                feature_type: SecurityFeatureType::InputValidation,
2580                implementation_quality: ImplementationQuality::Good,
2581                description: "Input validation framework detected".to_string(),
2582            });
2583        }
2584
2585        // Determine overall security level
2586        let level = self.determine_security_level(&vulnerabilities, &security_features);
2587        let recommendations =
2588            self.get_security_recommendations(&vulnerabilities, &security_features);
2589
2590        Ok(PythonSecurityAssessment {
2591            level,
2592            vulnerabilities_detected: vulnerabilities,
2593            security_features,
2594            recommendations,
2595        })
2596    }
2597
2598    /// Analyze Python performance patterns and issues
2599    pub fn analyze_performance(&self, content: &str) -> Result<PythonPerformanceAnalysis> {
2600        let mut optimizations = Vec::new();
2601        let mut issues = Vec::new();
2602
2603        // Detect performance optimizations
2604        for patterns in self.performance_patterns.values() {
2605            for pattern in patterns {
2606                for _captures in pattern.pattern.captures_iter(content) {
2607                    optimizations.push(PerformanceOptimization {
2608                        optimization_type: pattern.optimization_type.clone(),
2609                        impact_level: pattern.impact_level.clone(),
2610                        description: pattern.description.clone(),
2611                        best_practices_followed: true,
2612                    });
2613                }
2614            }
2615        }
2616
2617        // Detect performance issues
2618        if content.contains("for") && content.contains("for") && content.matches("for").count() > 1
2619        {
2620            issues.push(PerformanceIssue {
2621                issue_type: PerformanceIssueType::InEfficientLoops,
2622                severity: IssueSeverity::Medium,
2623                description: "Nested loops detected - consider optimization".to_string(),
2624                recommendation: "Use list comprehensions or optimize algorithm".to_string(),
2625            });
2626        }
2627
2628        if content.contains("def __del__") {
2629            issues.push(PerformanceIssue {
2630                issue_type: PerformanceIssueType::MemoryLeaks,
2631                severity: IssueSeverity::High,
2632                description: "Manual destructor detected - potential memory management issue"
2633                    .to_string(),
2634                recommendation: "Use context managers or weak references".to_string(),
2635            });
2636        }
2637
2638        // Calculate overall score
2639        let overall_score = self.calculate_performance_score(&optimizations, &issues);
2640        let recommendations = self.get_performance_recommendations(&optimizations, &issues);
2641
2642        Ok(PythonPerformanceAnalysis {
2643            overall_score,
2644            optimizations_detected: optimizations,
2645            performance_issues: issues,
2646            recommendations,
2647        })
2648    }
2649
2650    /// Analyze Python frameworks with enhanced details
2651    pub fn analyze_frameworks(&self, content: &str) -> Result<Vec<PythonFrameworkInfo>> {
2652        let mut frameworks = Vec::new();
2653
2654        for patterns in self.framework_patterns.values() {
2655            for pattern in patterns {
2656                if pattern.pattern.is_match(content) {
2657                    let framework_specific_analysis = match pattern.framework.as_str() {
2658                        "Django" => FrameworkSpecificAnalysis::Django(
2659                            self.analyze_django_specifics(content),
2660                        ),
2661                        "Flask" => {
2662                            FrameworkSpecificAnalysis::Flask(self.analyze_flask_specifics(content))
2663                        }
2664                        "FastAPI" => FrameworkSpecificAnalysis::FastAPI(
2665                            self.analyze_fastapi_specifics(content),
2666                        ),
2667                        "Pytest" => FrameworkSpecificAnalysis::Pytest(
2668                            self.analyze_pytest_specifics(content),
2669                        ),
2670                        _ => continue,
2671                    };
2672
2673                    frameworks.push(PythonFrameworkInfo {
2674                        name: pattern.framework.clone(),
2675                        confidence: pattern.confidence,
2676                        version_detected: None, // Could be enhanced to detect versions
2677                        features_used: pattern.features.clone(),
2678                        best_practices: self.get_framework_best_practices(&pattern.framework),
2679                        framework_specific_analysis,
2680                    });
2681                }
2682            }
2683        }
2684
2685        Ok(frameworks)
2686    }
2687
2688    /// Analyze Python type hints comprehensively
2689    pub fn analyze_type_hints(&self, content: &str) -> Result<PythonTypeHintAnalysis> {
2690        let mut type_hints_detected = Vec::new();
2691        let mut type_safety_issues = Vec::new();
2692        let mut modern_type_features = Vec::new();
2693
2694        // Detect type hints using patterns
2695        for patterns in self.type_hint_patterns.values() {
2696            for pattern in patterns {
2697                for captures in pattern.pattern.captures_iter(content) {
2698                    let full_match = captures.get(0).unwrap().as_str();
2699
2700                    let hint_type = self.parse_type_hint_type(&pattern.hint_type, &captures);
2701                    let is_generic = self.is_generic_type(&pattern.hint_type);
2702                    let has_constraints = self.has_type_constraints(&pattern.hint_type);
2703
2704                    type_hints_detected.push(TypeHintInfo {
2705                        location: full_match.to_string(),
2706                        hint_type,
2707                        complexity: pattern.complexity.clone(),
2708                        is_generic,
2709                        has_constraints,
2710                        python_version_required: pattern.python_version.clone(),
2711                    });
2712
2713                    // Check for modern type features
2714                    if pattern.python_version.starts_with("3.8")
2715                        || pattern.python_version.starts_with("3.9")
2716                        || pattern.python_version.starts_with("3.10")
2717                    {
2718                        let feature_type = self.get_modern_feature_type(&pattern.hint_type);
2719                        if let Some(feature_type) = feature_type {
2720                            modern_type_features.push(ModernTypeFeature {
2721                                feature_type,
2722                                python_version: pattern.python_version.clone(),
2723                                usage_count: 1,
2724                                description: format!(
2725                                    "Modern type feature: {name}",
2726                                    name = pattern.name
2727                                ),
2728                                is_best_practice: true,
2729                            });
2730                        }
2731                    }
2732                }
2733            }
2734        }
2735
2736        // Detect type safety issues
2737        self.detect_type_safety_issues(content, &mut type_safety_issues);
2738
2739        // Calculate type coverage
2740        let overall_coverage = self.calculate_type_coverage(content, &type_hints_detected);
2741        let type_coverage_score = self.get_coverage_score(overall_coverage);
2742
2743        // Generate recommendations
2744        let recommendations = self.get_type_hint_recommendations(
2745            &type_hints_detected,
2746            &type_safety_issues,
2747            overall_coverage,
2748        );
2749
2750        Ok(PythonTypeHintAnalysis {
2751            overall_coverage,
2752            type_coverage_score,
2753            type_hints_detected,
2754            type_safety_issues,
2755            modern_type_features,
2756            recommendations,
2757        })
2758    }
2759
2760    /// Analyze Python async/await patterns comprehensively
2761    pub fn analyze_async_await(&self, content: &str) -> Result<PythonAsyncAwaitAnalysis> {
2762        let mut async_functions_detected = Vec::new();
2763        let mut await_usage_patterns = Vec::new();
2764        let mut concurrency_patterns = Vec::new();
2765        let mut async_performance_issues = Vec::new();
2766        let mut async_security_issues = Vec::new();
2767        let mut modern_async_features = Vec::new();
2768
2769        // Analyze async functions
2770        self.analyze_async_functions(content, &mut async_functions_detected);
2771
2772        // Analyze await usage patterns
2773        self.analyze_await_usage(content, &mut await_usage_patterns);
2774
2775        // Analyze concurrency patterns
2776        self.analyze_concurrency_patterns(content, &mut concurrency_patterns);
2777
2778        // Detect async performance issues
2779        self.detect_async_performance_issues(content, &mut async_performance_issues);
2780
2781        // Detect async security issues
2782        self.detect_async_security_issues(content, &mut async_security_issues);
2783
2784        // Detect modern async features
2785        self.detect_modern_async_features(content, &mut modern_async_features);
2786
2787        // Calculate overall async score
2788        let overall_async_score = self.calculate_async_score(
2789            &async_functions_detected,
2790            &concurrency_patterns,
2791            &async_performance_issues,
2792            &async_security_issues,
2793        );
2794
2795        // Generate recommendations
2796        let recommendations = self.get_async_recommendations(
2797            &async_functions_detected,
2798            &await_usage_patterns,
2799            &concurrency_patterns,
2800            &async_performance_issues,
2801            &async_security_issues,
2802        );
2803
2804        Ok(PythonAsyncAwaitAnalysis {
2805            overall_async_score,
2806            async_functions_detected,
2807            await_usage_patterns,
2808            concurrency_patterns,
2809            async_performance_issues,
2810            async_security_issues,
2811            modern_async_features,
2812            recommendations,
2813        })
2814    }
2815
2816    /// Analyze Python package dependencies comprehensively
2817    pub fn analyze_package_dependencies(
2818        &self,
2819        content: &str,
2820    ) -> Result<PythonPackageDependencyAnalysis> {
2821        let mut requirements_files = Vec::new();
2822        let mut dependencies = Vec::new();
2823        let mut dependency_issues = Vec::new();
2824        let mut virtual_environments = Vec::new();
2825        let mut import_analysis = Vec::new();
2826        let mut security_vulnerabilities = Vec::new();
2827        let mut license_analysis = Vec::new();
2828
2829        // Analyze requirements files
2830        self.analyze_requirements_files(content, &mut requirements_files, &mut dependencies);
2831
2832        // Analyze imports
2833        self.analyze_imports(content, &mut import_analysis);
2834
2835        // Detect dependency issues
2836        self.detect_dependency_issues(
2837            content,
2838            &dependencies,
2839            &import_analysis,
2840            &mut dependency_issues,
2841        );
2842
2843        // Detect virtual environments
2844        self.detect_virtual_environments(content, &mut virtual_environments);
2845
2846        // Perform security vulnerability scanning
2847        self.scan_security_vulnerabilities(&dependencies, &mut security_vulnerabilities);
2848
2849        // Analyze licenses
2850        self.analyze_licenses(&dependencies, &mut license_analysis);
2851
2852        // Calculate overall health score
2853        let overall_health_score = self.calculate_dependency_health_score(
2854            &requirements_files,
2855            &dependencies,
2856            &dependency_issues,
2857            &security_vulnerabilities,
2858        );
2859
2860        // Generate recommendations
2861        let recommendations = self.get_dependency_recommendations(
2862            &requirements_files,
2863            &dependencies,
2864            &dependency_issues,
2865            &import_analysis,
2866            &security_vulnerabilities,
2867        );
2868
2869        Ok(PythonPackageDependencyAnalysis {
2870            overall_health_score,
2871            requirements_files,
2872            dependencies,
2873            dependency_issues,
2874            virtual_environments,
2875            import_analysis,
2876            security_vulnerabilities,
2877            license_analysis,
2878            recommendations,
2879        })
2880    }
2881
2882    /// Analyze requirements files
2883    fn analyze_requirements_files(
2884        &self,
2885        content: &str,
2886        requirements_files: &mut Vec<RequirementsFileInfo>,
2887        dependencies: &mut Vec<RequirementInfo>,
2888    ) {
2889        for patterns in self.dependency_patterns.values() {
2890            for pattern in patterns {
2891                if pattern.extraction_method == "line_by_line" {
2892                    // Handle requirements.txt format
2893                    for line in content.lines() {
2894                        if let Some(captures) = pattern.pattern.captures(line) {
2895                            let package_name = captures.get(1).unwrap().as_str();
2896                            let version_spec = captures
2897                                .get(2)
2898                                .and_then(|m| {
2899                                    captures.get(3).map(|v| {
2900                                        let m_str = m.as_str();
2901                                        let v_str = v.as_str();
2902                                        format!("{m_str}{v_str}")
2903                                    })
2904                                })
2905                                .unwrap_or_else(|| "*".to_string());
2906
2907                            dependencies.push(RequirementInfo {
2908                                name: package_name.to_string(),
2909                                version_spec,
2910                                source: RequirementSource::PyPI,
2911                                is_dev_dependency: false,
2912                                is_optional: false,
2913                                extras: Vec::new(),
2914                                markers: Vec::new(),
2915                                metadata: self.get_package_metadata(package_name),
2916                            });
2917                        }
2918                    }
2919
2920                    if !dependencies.is_empty() {
2921                        requirements_files.push(RequirementsFileInfo {
2922                            file_path: "requirements.txt".to_string(),
2923                            file_type: RequirementsFileType::RequirementsTxt,
2924                            dependencies_count: dependencies.len(),
2925                            has_version_pins: dependencies.iter().any(|d| d.version_spec != "*"),
2926                            has_hashes: false,
2927                            uses_constraints: false,
2928                            quality_score: self.assess_requirements_quality(dependencies),
2929                        });
2930                    }
2931                } else if pattern.extraction_method == "toml_array"
2932                    && content.contains("pyproject.toml")
2933                {
2934                    // Handle pyproject.toml format
2935                    if let Some(captures) = pattern.pattern.captures(content) {
2936                        let deps_str = captures.get(1).unwrap().as_str();
2937                        for dep in deps_str.split(',') {
2938                            let clean_dep = dep.trim().trim_matches('"').trim_matches('\'');
2939                            if !clean_dep.is_empty() {
2940                                let parts: Vec<&str> =
2941                                    clean_dep.split(['>', '<', '=', '!', '~']).collect();
2942                                let package_name = parts[0].trim();
2943                                let version_spec = if parts.len() > 1 {
2944                                    clean_dep[package_name.len()..].to_string()
2945                                } else {
2946                                    "*".to_string()
2947                                };
2948
2949                                dependencies.push(RequirementInfo {
2950                                    name: package_name.to_string(),
2951                                    version_spec,
2952                                    source: RequirementSource::PyPI,
2953                                    is_dev_dependency: false,
2954                                    is_optional: false,
2955                                    extras: Vec::new(),
2956                                    markers: Vec::new(),
2957                                    metadata: self.get_package_metadata(package_name),
2958                                });
2959                            }
2960                        }
2961
2962                        requirements_files.push(RequirementsFileInfo {
2963                            file_path: "pyproject.toml".to_string(),
2964                            file_type: RequirementsFileType::PyprojectToml,
2965                            dependencies_count: dependencies.len(),
2966                            has_version_pins: dependencies.iter().any(|d| d.version_spec != "*"),
2967                            has_hashes: false,
2968                            uses_constraints: false,
2969                            quality_score: self.assess_requirements_quality(dependencies),
2970                        });
2971                    }
2972                }
2973            }
2974        }
2975    }
2976
2977    /// Analyze import statements
2978    fn analyze_imports(&self, content: &str, import_analysis: &mut Vec<ImportAnalysisInfo>) {
2979        if let Some(import_patterns) = self.dependency_patterns.get("imports") {
2980            for pattern in import_patterns {
2981                for captures in pattern.pattern.captures_iter(content) {
2982                    let module_name = if pattern.name == "Relative Import" && captures.len() > 2 {
2983                        format!(
2984                            "{}{}",
2985                            captures.get(1).unwrap().as_str(),
2986                            captures.get(2).unwrap().as_str()
2987                        )
2988                    } else {
2989                        captures.get(1).unwrap().as_str().to_string()
2990                    };
2991
2992                    let import_type = self.classify_import_type(&pattern.name);
2993                    let module_category = self.categorize_module(&module_name);
2994                    let usage_count = content.matches(&module_name).count();
2995                    let is_unused = usage_count <= 1; // Only the import itself
2996                    let import_issues =
2997                        self.detect_import_issues(&pattern.name, &module_name, content);
2998
2999                    import_analysis.push(ImportAnalysisInfo {
3000                        import_statement: captures.get(0).unwrap().as_str().to_string(),
3001                        import_type,
3002                        module_category,
3003                        usage_count,
3004                        is_unused,
3005                        import_issues,
3006                        optimization_suggestions: self
3007                            .get_import_optimization_suggestions(&pattern.name, &module_name),
3008                    });
3009                }
3010            }
3011        }
3012    }
3013
3014    /// Detect dependency issues
3015    fn detect_dependency_issues(
3016        &self,
3017        _content: &str,
3018        dependencies: &[RequirementInfo],
3019        import_analysis: &[ImportAnalysisInfo],
3020        issues: &mut Vec<DependencyIssue>,
3021    ) {
3022        // Detect unused dependencies
3023        for dep in dependencies {
3024            let is_imported = import_analysis.iter().any(|imp| {
3025                imp.import_statement.contains(&dep.name)
3026                    || imp.import_statement.contains(&dep.name.replace("-", "_"))
3027            });
3028
3029            if !is_imported {
3030                issues.push(DependencyIssue {
3031                    issue_type: DependencyIssueType::UnusedDependency,
3032                    severity: DependencyIssueSeverity::Low,
3033                    affected_packages: vec![dep.name.clone()],
3034                    description: format!(
3035                        "Dependency '{name}' declared but not imported",
3036                        name = dep.name
3037                    ),
3038                    recommendation: "Remove unused dependency or add import statement".to_string(),
3039                    auto_fixable: false,
3040                });
3041            }
3042        }
3043
3044        // Detect missing dependencies
3045        for import in import_analysis {
3046            if matches!(import.module_category, ModuleCategory::ThirdParty) {
3047                let module_root = import
3048                    .import_statement
3049                    .split_whitespace()
3050                    .nth(1)
3051                    .unwrap_or("")
3052                    .split('.')
3053                    .next()
3054                    .unwrap_or("");
3055
3056                let is_declared = dependencies.iter().any(|dep| {
3057                    dep.name == module_root || dep.name.replace("-", "_") == module_root
3058                });
3059
3060                if !is_declared && !module_root.is_empty() {
3061                    issues.push(DependencyIssue {
3062                        issue_type: DependencyIssueType::MissingDependency,
3063                        severity: DependencyIssueSeverity::High,
3064                        affected_packages: vec![module_root.to_string()],
3065                        description: format!(
3066                            "Module '{module_root}' imported but not declared as dependency"
3067                        ),
3068                        recommendation: "Add missing dependency to requirements".to_string(),
3069                        auto_fixable: true,
3070                    });
3071                }
3072            }
3073        }
3074
3075        // Detect unpinned versions
3076        for dep in dependencies {
3077            if dep.version_spec == "*" || dep.version_spec.is_empty() {
3078                issues.push(DependencyIssue {
3079                    issue_type: DependencyIssueType::UnpinnedVersion,
3080                    severity: DependencyIssueSeverity::Medium,
3081                    affected_packages: vec![dep.name.clone()],
3082                    description: format!(
3083                        "Dependency '{name}' has no version constraint",
3084                        name = dep.name
3085                    ),
3086                    recommendation: "Pin dependency versions for reproducible builds".to_string(),
3087                    auto_fixable: false,
3088                });
3089            }
3090        }
3091
3092        // Detect deprecated packages
3093        let deprecated_packages = ["imp", "optparse", "platform", "distutils"];
3094        for dep in dependencies {
3095            if deprecated_packages.contains(&dep.name.as_str()) {
3096                issues.push(DependencyIssue {
3097                    issue_type: DependencyIssueType::DeprecatedPackage,
3098                    severity: DependencyIssueSeverity::Medium,
3099                    affected_packages: vec![dep.name.clone()],
3100                    description: format!("Package '{name}' is deprecated", name = dep.name),
3101                    recommendation: "Consider migrating to modern alternatives".to_string(),
3102                    auto_fixable: false,
3103                });
3104            }
3105        }
3106    }
3107
3108    /// Detect virtual environments
3109    fn detect_virtual_environments(
3110        &self,
3111        content: &str,
3112        virtual_environments: &mut Vec<VirtualEnvironmentInfo>,
3113    ) {
3114        // Check for virtual environment indicators
3115        if content.contains("venv") || content.contains("virtualenv") {
3116            virtual_environments.push(VirtualEnvironmentInfo {
3117                env_type: VirtualEnvironmentType::Venv,
3118                location: "./venv".to_string(),
3119                python_version: "3.x".to_string(),
3120                is_active: true,
3121                packages_count: 0,
3122                env_variables: Vec::new(),
3123                configuration: VirtualEnvironmentConfig {
3124                    isolated: true,
3125                    system_site_packages: false,
3126                    pip_version: None,
3127                    setuptools_version: None,
3128                    custom_configurations: Vec::new(),
3129                },
3130            });
3131        }
3132
3133        if content.contains("conda") || content.contains("environment.yml") {
3134            virtual_environments.push(VirtualEnvironmentInfo {
3135                env_type: VirtualEnvironmentType::Conda,
3136                location: "conda environment".to_string(),
3137                python_version: "3.x".to_string(),
3138                is_active: true,
3139                packages_count: 0,
3140                env_variables: Vec::new(),
3141                configuration: VirtualEnvironmentConfig {
3142                    isolated: true,
3143                    system_site_packages: false,
3144                    pip_version: None,
3145                    setuptools_version: None,
3146                    custom_configurations: Vec::new(),
3147                },
3148            });
3149        }
3150
3151        if content.contains("pipenv") || content.contains("Pipfile") {
3152            virtual_environments.push(VirtualEnvironmentInfo {
3153                env_type: VirtualEnvironmentType::Pipenv,
3154                location: "pipenv environment".to_string(),
3155                python_version: "3.x".to_string(),
3156                is_active: true,
3157                packages_count: 0,
3158                env_variables: Vec::new(),
3159                configuration: VirtualEnvironmentConfig {
3160                    isolated: true,
3161                    system_site_packages: false,
3162                    pip_version: None,
3163                    setuptools_version: None,
3164                    custom_configurations: Vec::new(),
3165                },
3166            });
3167        }
3168    }
3169
3170    /// Scan for security vulnerabilities
3171    fn scan_security_vulnerabilities(
3172        &self,
3173        dependencies: &[RequirementInfo],
3174        vulnerabilities: &mut Vec<SecurityVulnerabilityInfo>,
3175    ) {
3176        // Simplified vulnerability database - in production, this would query real databases
3177        let known_vulnerabilities = vec![
3178            ("urllib3", "1.25.8", "CVE-2020-26137", "Critical"),
3179            ("requests", "2.19.1", "CVE-2018-18074", "High"),
3180            ("pyyaml", "5.3.1", "CVE-2020-14343", "High"),
3181            ("django", "2.2.12", "CVE-2020-13254", "Medium"),
3182            ("flask", "1.1.1", "CVE-2019-1010083", "Medium"),
3183        ];
3184
3185        for dep in dependencies {
3186            for (vuln_package, vuln_version, cve_id, severity) in &known_vulnerabilities {
3187                if dep.name == *vuln_package {
3188                    let severity_enum = match *severity {
3189                        "Critical" => SecurityVulnerabilitySeverity::Critical,
3190                        "High" => SecurityVulnerabilitySeverity::High,
3191                        "Medium" => SecurityVulnerabilitySeverity::Medium,
3192                        _ => SecurityVulnerabilitySeverity::Low,
3193                    };
3194
3195                    vulnerabilities.push(SecurityVulnerabilityInfo {
3196                        cve_id: Some(cve_id.to_string()),
3197                        advisory_id: None,
3198                        package_name: dep.name.clone(),
3199                        affected_versions: vec![vuln_version.to_string()],
3200                        fixed_version: Some("Latest".to_string()),
3201                        severity: severity_enum,
3202                        vulnerability_type: VulnerabilityCategory::CodeExecution,
3203                        description: format!(
3204                            "Security vulnerability in {vuln_package} {vuln_version}"
3205                        ),
3206                        references: vec![format!(
3207                            "https://cve.mitre.org/cgi-bin/cvename.cgi?name={cve_id}"
3208                        )],
3209                        published_date: Some("2020-01-01".to_string()),
3210                        last_modified: Some("2020-01-01".to_string()),
3211                    });
3212                }
3213            }
3214        }
3215    }
3216
3217    /// Analyze package licenses
3218    fn analyze_licenses(
3219        &self,
3220        dependencies: &[RequirementInfo],
3221        license_analysis: &mut Vec<LicenseInfo>,
3222    ) {
3223        for dep in dependencies {
3224            // Use metadata from package
3225            let license_type = self.parse_license_type(&dep.metadata.license);
3226            let compatibility = self.assess_license_compatibility(&license_type);
3227
3228            license_analysis.push(LicenseInfo {
3229                package_name: dep.name.clone(),
3230                license_type: license_type.clone(),
3231                license_text: None,
3232                compatibility,
3233                commercial_use_allowed: self.is_commercial_use_allowed(&license_type),
3234                distribution_allowed: self.is_distribution_allowed(&license_type),
3235                modification_allowed: self.is_modification_allowed(&license_type),
3236                patent_grant: self.has_patent_grant(&license_type),
3237                copyleft: self.is_copyleft(&license_type),
3238            });
3239        }
3240    }
3241
3242    /// Helper methods for dependency analysis
3243    fn get_package_metadata(&self, package_name: &str) -> PackageMetadata {
3244        // Simplified metadata - in production, this would query PyPI API
3245        PackageMetadata {
3246            description: format!("Package: {package_name}"),
3247            author: "Unknown".to_string(),
3248            license: "MIT".to_string(),
3249            homepage: None,
3250            documentation: None,
3251            last_updated: None,
3252            download_count: None,
3253            maintenance_status: MaintenanceStatus::Unknown,
3254        }
3255    }
3256
3257    fn assess_requirements_quality(
3258        &self,
3259        dependencies: &[RequirementInfo],
3260    ) -> DependencyQualityScore {
3261        let pinned_count = dependencies
3262            .iter()
3263            .filter(|d| d.version_spec != "*")
3264            .count();
3265        let pinned_ratio = if dependencies.is_empty() {
3266            0.0
3267        } else {
3268            pinned_count as f32 / dependencies.len() as f32
3269        };
3270
3271        match pinned_ratio {
3272            r if r >= 0.9 => DependencyQualityScore::Excellent,
3273            r if r >= 0.7 => DependencyQualityScore::Good,
3274            r if r >= 0.5 => DependencyQualityScore::Fair,
3275            r if r >= 0.3 => DependencyQualityScore::Poor,
3276            _ => DependencyQualityScore::Critical,
3277        }
3278    }
3279
3280    fn classify_import_type(&self, pattern_name: &str) -> ImportType {
3281        match pattern_name {
3282            "Standard Import" => ImportType::StandardImport,
3283            "From Import" => ImportType::FromImport,
3284            "Star Import" => ImportType::StarImport,
3285            "Alias Import" => ImportType::AliasImport,
3286            "Relative Import" => ImportType::RelativeImport,
3287            _ => ImportType::StandardImport,
3288        }
3289    }
3290
3291    fn categorize_module(&self, module_name: &str) -> ModuleCategory {
3292        // Standard library modules
3293        let stdlib_modules = vec![
3294            "os",
3295            "sys",
3296            "re",
3297            "json",
3298            "urllib",
3299            "http",
3300            "datetime",
3301            "collections",
3302            "itertools",
3303            "functools",
3304            "pathlib",
3305            "typing",
3306            "asyncio",
3307            "threading",
3308            "multiprocessing",
3309            "subprocess",
3310            "logging",
3311            "unittest",
3312            "sqlite3",
3313        ];
3314
3315        let root_module = module_name.split('.').next().unwrap_or(module_name);
3316
3317        if stdlib_modules.contains(&root_module) {
3318            ModuleCategory::StandardLibrary
3319        } else if root_module.starts_with('.') {
3320            ModuleCategory::Local
3321        } else {
3322            ModuleCategory::ThirdParty
3323        }
3324    }
3325
3326    fn detect_import_issues(
3327        &self,
3328        pattern_name: &str,
3329        module_name: &str,
3330        content: &str,
3331    ) -> Vec<ImportIssue> {
3332        let mut issues = Vec::new();
3333
3334        if pattern_name == "Star Import" {
3335            issues.push(ImportIssue::StarImportDangerous);
3336        }
3337
3338        // Check for circular imports (simplified)
3339        if content.contains(&format!("from {module_name} import"))
3340            && content.contains(&format!("import {module_name}"))
3341        {
3342            issues.push(ImportIssue::CircularImport);
3343        }
3344
3345        // Check for deprecated modules
3346        let deprecated_modules = ["imp", "optparse", "platform.dist"];
3347        if deprecated_modules
3348            .iter()
3349            .any(|&dep| module_name.contains(dep))
3350        {
3351            issues.push(ImportIssue::DeprecatedImport);
3352        }
3353
3354        issues
3355    }
3356
3357    fn get_import_optimization_suggestions(
3358        &self,
3359        pattern_name: &str,
3360        module_name: &str,
3361    ) -> Vec<String> {
3362        let mut suggestions = Vec::new();
3363
3364        if pattern_name == "Star Import" {
3365            suggestions.push("Replace star import with specific imports".to_string());
3366        }
3367
3368        if module_name == "pandas" || module_name == "numpy" {
3369            suggestions.push("Consider lazy loading for large libraries".to_string());
3370        }
3371
3372        suggestions
3373    }
3374
3375    fn parse_license_type(&self, license_str: &str) -> LicenseType {
3376        match license_str.to_lowercase().as_str() {
3377            "mit" => LicenseType::MIT,
3378            "apache-2.0" | "apache 2.0" => LicenseType::Apache2,
3379            "gpl-2.0" | "gpl v2" => LicenseType::GPL2,
3380            "gpl-3.0" | "gpl v3" => LicenseType::GPL3,
3381            "bsd-2-clause" => LicenseType::BSD2Clause,
3382            "bsd-3-clause" => LicenseType::BSD3Clause,
3383            "lgpl" => LicenseType::LGPL,
3384            "mozilla" | "mpl-2.0" => LicenseType::Mozilla,
3385            "unlicense" => LicenseType::Unlicense,
3386            _ => LicenseType::Unknown,
3387        }
3388    }
3389
3390    fn assess_license_compatibility(&self, license_type: &LicenseType) -> LicenseCompatibility {
3391        match license_type {
3392            LicenseType::MIT
3393            | LicenseType::Apache2
3394            | LicenseType::BSD2Clause
3395            | LicenseType::BSD3Clause => LicenseCompatibility::Compatible,
3396            LicenseType::GPL2 | LicenseType::GPL3 => LicenseCompatibility::RequiresReview,
3397            LicenseType::LGPL => LicenseCompatibility::ConditionallyCompatible,
3398            _ => LicenseCompatibility::Unknown,
3399        }
3400    }
3401
3402    fn is_commercial_use_allowed(&self, license_type: &LicenseType) -> bool {
3403        !matches!(license_type, LicenseType::GPL2 | LicenseType::GPL3)
3404    }
3405
3406    fn is_distribution_allowed(&self, license_type: &LicenseType) -> bool {
3407        !matches!(license_type, LicenseType::Proprietary)
3408    }
3409
3410    fn is_modification_allowed(&self, license_type: &LicenseType) -> bool {
3411        !matches!(license_type, LicenseType::Proprietary)
3412    }
3413
3414    fn has_patent_grant(&self, license_type: &LicenseType) -> bool {
3415        matches!(license_type, LicenseType::Apache2 | LicenseType::Mozilla)
3416    }
3417
3418    fn is_copyleft(&self, license_type: &LicenseType) -> bool {
3419        matches!(
3420            license_type,
3421            LicenseType::GPL2 | LicenseType::GPL3 | LicenseType::LGPL
3422        )
3423    }
3424
3425    fn calculate_dependency_health_score(
3426        &self,
3427        requirements_files: &[RequirementsFileInfo],
3428        dependencies: &[RequirementInfo],
3429        issues: &[DependencyIssue],
3430        vulnerabilities: &[SecurityVulnerabilityInfo],
3431    ) -> i32 {
3432        let mut score = 100;
3433
3434        // Deduct points for issues
3435        for issue in issues {
3436            let deduction = match issue.severity {
3437                DependencyIssueSeverity::Critical => 20,
3438                DependencyIssueSeverity::High => 15,
3439                DependencyIssueSeverity::Medium => 10,
3440                DependencyIssueSeverity::Low => 5,
3441                DependencyIssueSeverity::Info => 2,
3442            };
3443            score -= deduction;
3444        }
3445
3446        // Deduct points for vulnerabilities
3447        for vuln in vulnerabilities {
3448            let deduction = match vuln.severity {
3449                SecurityVulnerabilitySeverity::Critical => 25,
3450                SecurityVulnerabilitySeverity::High => 20,
3451                SecurityVulnerabilitySeverity::Medium => 15,
3452                SecurityVulnerabilitySeverity::Low => 10,
3453                _ => 5,
3454            };
3455            score -= deduction;
3456        }
3457
3458        // Add points for good practices
3459        if !requirements_files.is_empty() {
3460            score += 10;
3461        }
3462
3463        let pinned_deps = dependencies
3464            .iter()
3465            .filter(|d| d.version_spec != "*")
3466            .count();
3467        let pinned_ratio = if dependencies.is_empty() {
3468            0.0
3469        } else {
3470            pinned_deps as f32 / dependencies.len() as f32
3471        };
3472
3473        score += (pinned_ratio * 20.0) as i32;
3474
3475        score.clamp(0, 100)
3476    }
3477
3478    fn get_dependency_recommendations(
3479        &self,
3480        requirements_files: &[RequirementsFileInfo],
3481        dependencies: &[RequirementInfo],
3482        issues: &[DependencyIssue],
3483        import_analysis: &[ImportAnalysisInfo],
3484        vulnerabilities: &[SecurityVulnerabilityInfo],
3485    ) -> Vec<String> {
3486        let mut recommendations = Vec::new();
3487
3488        if requirements_files.is_empty() {
3489            recommendations
3490                .push("Create a requirements.txt file to track dependencies".to_string());
3491        }
3492
3493        let unpinned_count = dependencies
3494            .iter()
3495            .filter(|d| d.version_spec == "*")
3496            .count();
3497        if unpinned_count > 0 {
3498            recommendations.push(format!(
3499                "Pin {unpinned_count} unpinned dependencies for reproducible builds"
3500            ));
3501        }
3502
3503        if !vulnerabilities.is_empty() {
3504            recommendations.push(format!(
3505                "Update {} packages with known security vulnerabilities",
3506                vulnerabilities.len()
3507            ));
3508        }
3509
3510        let unused_imports = import_analysis.iter().filter(|i| i.is_unused).count();
3511        if unused_imports > 0 {
3512            recommendations.push(format!("Remove {unused_imports} unused import statements"));
3513        }
3514
3515        let star_imports = import_analysis
3516            .iter()
3517            .filter(|i| matches!(i.import_type, ImportType::StarImport))
3518            .count();
3519        if star_imports > 0 {
3520            recommendations.push(format!(
3521                "Replace {star_imports} star imports with specific imports"
3522            ));
3523        }
3524
3525        let critical_issues = issues
3526            .iter()
3527            .filter(|i| matches!(i.severity, DependencyIssueSeverity::Critical))
3528            .count();
3529        if critical_issues > 0 {
3530            recommendations.push("Address critical dependency issues immediately".to_string());
3531        }
3532
3533        recommendations
3534            .push("Consider using dependency scanning tools like Safety or Bandit".to_string());
3535        recommendations.push("Set up automated dependency updates with Dependabot".to_string());
3536
3537        recommendations
3538    }
3539
3540    /// Analyze modern Python features comprehensively
3541    pub fn analyze_modern_features(&self, content: &str) -> Result<ModernPythonFeatureAnalysis> {
3542        let mut dataclass_features = Vec::new();
3543        let mut context_manager_features = Vec::new();
3544        let mut fstring_features = Vec::new();
3545        let mut pattern_matching_features = Vec::new();
3546        let mut generator_features = Vec::new();
3547        let mut decorator_features = Vec::new();
3548        let mut modern_syntax_features = Vec::new();
3549
3550        // Analyze dataclasses
3551        self.analyze_dataclasses(content, &mut dataclass_features);
3552
3553        // Analyze context managers
3554        self.analyze_context_managers(content, &mut context_manager_features);
3555
3556        // Analyze f-strings
3557        self.analyze_fstrings(content, &mut fstring_features);
3558
3559        // Analyze pattern matching
3560        self.analyze_pattern_matching(content, &mut pattern_matching_features);
3561
3562        // Analyze generators
3563        self.analyze_generators(content, &mut generator_features);
3564
3565        // Analyze modern decorators
3566        self.analyze_modern_decorators(content, &mut decorator_features);
3567
3568        // Analyze modern syntax
3569        self.analyze_modern_syntax(content, &mut modern_syntax_features);
3570
3571        // Detect Python version and compatibility
3572        let python_version_detected = self.detect_python_version(content);
3573
3574        // Calculate overall modernity score
3575        let overall_modernity_score = self.calculate_modernity_score(
3576            &dataclass_features,
3577            &context_manager_features,
3578            &fstring_features,
3579            &pattern_matching_features,
3580            &generator_features,
3581            &decorator_features,
3582            &modern_syntax_features,
3583        );
3584
3585        // Generate recommendations
3586        let recommendations = self.get_modern_feature_recommendations(
3587            &dataclass_features,
3588            &context_manager_features,
3589            &fstring_features,
3590            &pattern_matching_features,
3591            &generator_features,
3592            &decorator_features,
3593            &modern_syntax_features,
3594            &python_version_detected,
3595        );
3596
3597        Ok(ModernPythonFeatureAnalysis {
3598            overall_modernity_score,
3599            python_version_detected,
3600            dataclass_features,
3601            context_manager_features,
3602            fstring_features,
3603            pattern_matching_features,
3604            generator_features,
3605            decorator_features,
3606            modern_syntax_features,
3607            recommendations,
3608        })
3609    }
3610
3611    /// Analyze dataclass usage patterns
3612    fn analyze_dataclasses(&self, content: &str, dataclass_features: &mut Vec<DataclassInfo>) {
3613        if let Some(patterns) = self.modern_feature_patterns.get("dataclass") {
3614            for pattern in patterns {
3615                for captures in pattern.pattern.captures_iter(content) {
3616                    let full_match = captures.get(0).unwrap().as_str();
3617
3618                    let dataclass_type = match pattern.name.as_str() {
3619                        "Dataclass Decorator" => DataclassType::StandardDataclass,
3620                        "Pydantic Model" => DataclassType::PydanticModel,
3621                        "Named Tuple" => DataclassType::NamedTuple,
3622                        _ => DataclassType::StandardDataclass,
3623                    };
3624
3625                    let class_name = self.extract_dataclass_name(full_match, content);
3626                    let fields = self.analyze_dataclass_fields(content, &class_name);
3627                    let features_used = self.detect_dataclass_features(content, &class_name);
3628                    let complexity = self.assess_dataclass_complexity(&fields, &features_used);
3629                    let best_practices_score =
3630                        self.score_dataclass_best_practices(&fields, &features_used);
3631                    let recommendations =
3632                        self.get_dataclass_recommendations(&features_used, best_practices_score);
3633
3634                    dataclass_features.push(DataclassInfo {
3635                        class_name,
3636                        dataclass_type,
3637                        fields,
3638                        features_used,
3639                        complexity,
3640                        best_practices_score,
3641                        recommendations,
3642                    });
3643                }
3644            }
3645        }
3646    }
3647
3648    /// Analyze context manager usage
3649    fn analyze_context_managers(
3650        &self,
3651        content: &str,
3652        context_features: &mut Vec<ContextManagerInfo>,
3653    ) {
3654        if let Some(patterns) = self.modern_feature_patterns.get("context_manager") {
3655            for pattern in patterns {
3656                for captures in pattern.pattern.captures_iter(content) {
3657                    let full_match = captures.get(0).unwrap().as_str();
3658
3659                    let context_type = match pattern.name.as_str() {
3660                        "With Statement" => ContextManagerType::BuiltInFileManager,
3661                        "Async With" => ContextManagerType::AsyncContextManager,
3662                        "Context Manager Protocol" => ContextManagerType::CustomContextManager,
3663                        "Contextlib Manager" => ContextManagerType::ContextlibManager,
3664                        _ => ContextManagerType::BuiltInFileManager,
3665                    };
3666
3667                    let usage_pattern = self.analyze_context_usage_pattern(content, full_match);
3668                    let resource_management =
3669                        self.assess_resource_management_quality(content, full_match);
3670                    let error_handling = self.assess_context_error_handling(content, full_match);
3671                    let is_async = pattern.name.contains("Async");
3672                    let nested_level = self.calculate_context_nesting_level(content, full_match);
3673                    let best_practices_followed =
3674                        self.check_context_best_practices(content, full_match);
3675
3676                    context_features.push(ContextManagerInfo {
3677                        context_type,
3678                        usage_pattern,
3679                        resource_management,
3680                        error_handling,
3681                        is_async,
3682                        nested_level,
3683                        best_practices_followed,
3684                    });
3685                }
3686            }
3687        }
3688    }
3689
3690    /// Analyze f-string usage
3691    fn analyze_fstrings(&self, content: &str, fstring_features: &mut Vec<FStringInfo>) {
3692        if let Some(patterns) = self.modern_feature_patterns.get("fstring") {
3693            for pattern in patterns {
3694                for captures in pattern.pattern.captures_iter(content) {
3695                    let expression = captures.get(0).unwrap().as_str().to_string();
3696
3697                    let complexity = self.assess_fstring_complexity(&expression);
3698                    let features_used = self.detect_fstring_features(&expression);
3699                    let performance_impact =
3700                        self.assess_fstring_performance(&expression, &features_used);
3701                    let formatting_quality = self.assess_formatting_quality(&expression);
3702                    let readability_score = self.calculate_fstring_readability(&expression);
3703
3704                    fstring_features.push(FStringInfo {
3705                        expression,
3706                        complexity,
3707                        features_used,
3708                        performance_impact,
3709                        formatting_quality,
3710                        readability_score,
3711                    });
3712                }
3713            }
3714        }
3715    }
3716
3717    /// Analyze pattern matching (Python 3.10+)
3718    fn analyze_pattern_matching(
3719        &self,
3720        content: &str,
3721        pattern_features: &mut Vec<PatternMatchingInfo>,
3722    ) {
3723        if let Some(_patterns) = self.modern_feature_patterns.get("pattern_matching") {
3724            // Look for complete match statements
3725            let match_regex = Regex::new(r"(?m)^(\s*)match\s+[^:]+:(.*?)$").unwrap();
3726            for captures in match_regex.captures_iter(content) {
3727                let match_statement = captures.get(0).unwrap().as_str().to_string();
3728
3729                let pattern_types = self.analyze_match_patterns(&match_statement);
3730                let complexity = self.assess_pattern_complexity(&pattern_types);
3731                let has_guards = match_statement.contains("if ");
3732                let is_exhaustive = self.check_pattern_exhaustiveness(&match_statement);
3733                let performance_characteristics =
3734                    self.assess_match_performance(&pattern_types, &match_statement);
3735                let best_practices_score =
3736                    self.score_pattern_best_practices(&pattern_types, has_guards, is_exhaustive);
3737
3738                pattern_features.push(PatternMatchingInfo {
3739                    match_statement,
3740                    pattern_types,
3741                    complexity,
3742                    has_guards,
3743                    is_exhaustive,
3744                    performance_characteristics,
3745                    best_practices_score,
3746                });
3747            }
3748        }
3749    }
3750
3751    /// Analyze generator patterns
3752    fn analyze_generators(&self, content: &str, generator_features: &mut Vec<GeneratorInfo>) {
3753        if let Some(patterns) = self.modern_feature_patterns.get("generator") {
3754            for pattern in patterns {
3755                for captures in pattern.pattern.captures_iter(content) {
3756                    let full_match = captures.get(0).unwrap().as_str();
3757
3758                    let generator_type = match pattern.name.as_str() {
3759                        "Generator Function" => GeneratorType::GeneratorFunction,
3760                        "Generator Expression" => GeneratorType::GeneratorExpression,
3761                        "Async Generator" => GeneratorType::AsyncGenerator,
3762                        _ => GeneratorType::GeneratorFunction,
3763                    };
3764
3765                    let usage_pattern = self.classify_generator_usage_pattern(content, full_match);
3766                    let memory_efficiency =
3767                        self.assess_generator_memory_efficiency(content, full_match);
3768                    let complexity = self.assess_generator_complexity(content, full_match);
3769                    let is_async = pattern.name.contains("Async");
3770                    let yield_analysis = self.analyze_yield_usage(content, full_match);
3771                    let optimization_opportunities =
3772                        self.identify_generator_optimizations(content, full_match);
3773
3774                    generator_features.push(GeneratorInfo {
3775                        generator_type,
3776                        usage_pattern,
3777                        memory_efficiency,
3778                        complexity,
3779                        is_async,
3780                        yield_analysis,
3781                        optimization_opportunities,
3782                    });
3783                }
3784            }
3785        }
3786    }
3787
3788    /// Analyze modern decorator usage
3789    fn analyze_modern_decorators(
3790        &self,
3791        content: &str,
3792        decorator_features: &mut Vec<ModernDecoratorInfo>,
3793    ) {
3794        let decorator_regex = Regex::new(r"@(\w+)(?:\([^)]*\))?").unwrap();
3795        for captures in decorator_regex.captures_iter(content) {
3796            let decorator_name = captures.get(1).unwrap().as_str().to_string();
3797            let full_decorator = captures.get(0).unwrap().as_str();
3798
3799            let decorator_category = self.classify_decorator_category(&decorator_name);
3800            let usage_pattern = self.analyze_decorator_usage_pattern(content, full_decorator);
3801            let complexity = self.assess_decorator_complexity(full_decorator);
3802            let is_factory = full_decorator.contains('(');
3803            let is_async = content.contains("async def") && content.contains(&decorator_name);
3804            let parameters = self.extract_decorator_parameters(full_decorator);
3805            let best_practices_score =
3806                self.score_decorator_best_practices(&decorator_category, &usage_pattern);
3807
3808            decorator_features.push(ModernDecoratorInfo {
3809                decorator_name,
3810                decorator_category,
3811                usage_pattern,
3812                complexity,
3813                is_factory,
3814                is_async,
3815                parameters,
3816                best_practices_score,
3817            });
3818        }
3819    }
3820
3821    /// Analyze modern syntax features
3822    fn analyze_modern_syntax(&self, content: &str, syntax_features: &mut Vec<ModernSyntaxInfo>) {
3823        if let Some(patterns) = self.modern_feature_patterns.get("modern_syntax") {
3824            for pattern in patterns {
3825                let usage_count = pattern.pattern.find_iter(content).count();
3826                if usage_count > 0 {
3827                    let feature_type = match pattern.name.as_str() {
3828                        "Walrus Operator" => ModernSyntaxType::WalrusOperator,
3829                        "Positional Only Parameters" => ModernSyntaxType::PositionalOnlyParams,
3830                        "Union Type Operator" => ModernSyntaxType::TypeUnionOperator,
3831                        "Dictionary Union" => ModernSyntaxType::DictUnionOperator,
3832                        "Generic Type Hints" => ModernSyntaxType::GenericTypeHints,
3833                        _ => ModernSyntaxType::WalrusOperator,
3834                    };
3835
3836                    let complexity = self.assess_syntax_complexity(content, &pattern.pattern);
3837                    let best_practices_followed =
3838                        self.check_syntax_best_practices(content, &feature_type);
3839                    let migration_suggestions =
3840                        self.get_syntax_migration_suggestions(&feature_type, usage_count);
3841
3842                    syntax_features.push(ModernSyntaxInfo {
3843                        feature_type,
3844                        python_version: pattern.python_version.clone(),
3845                        usage_count,
3846                        complexity,
3847                        best_practices_followed,
3848                        migration_suggestions,
3849                    });
3850                }
3851            }
3852        }
3853    }
3854
3855    /// Detect minimum Python version required
3856    fn detect_python_version(&self, content: &str) -> PythonVersionDetected {
3857        let mut features_by_version = Vec::new();
3858        let mut compatibility_issues = Vec::new();
3859        let mut minimum_version = "3.6".to_string(); // Default modern minimum
3860
3861        // Check for version-specific features
3862        for patterns in self.modern_feature_patterns.values() {
3863            for pattern in patterns {
3864                if pattern.pattern.is_match(content) {
3865                    let version_required = pattern.python_version.clone();
3866
3867                    // Update minimum version if this feature requires newer version
3868                    if self.is_newer_version(&version_required, &minimum_version) {
3869                        minimum_version = version_required.clone();
3870                    }
3871
3872                    features_by_version.push(VersionFeature {
3873                        feature_name: pattern.name.clone(),
3874                        python_version: version_required,
3875                        usage_count: pattern.pattern.find_iter(content).count(),
3876                        is_best_practice: matches!(
3877                            pattern.complexity,
3878                            FeatureComplexity::Simple | FeatureComplexity::Moderate
3879                        ),
3880                    });
3881                }
3882            }
3883        }
3884
3885        // Check for compatibility issues
3886        if content.contains("print ") && !content.contains("print(") {
3887            compatibility_issues.push(CompatibilityIssue {
3888                issue_type: CompatibilityIssueType::SyntaxError,
3889                severity: CompatibilitySeverity::Critical,
3890                feature_name: "Print Statement".to_string(),
3891                required_version: "2.x".to_string(),
3892                description: "Print statement syntax not supported in Python 3".to_string(),
3893                recommendation: "Use print() function instead".to_string(),
3894            });
3895        }
3896
3897        PythonVersionDetected {
3898            minimum_version,
3899            features_by_version,
3900            compatibility_issues,
3901        }
3902    }
3903
3904    /// Helper methods for modern feature analysis
3905    fn extract_dataclass_name(&self, _match: &str, content: &str) -> String {
3906        // Look for class definition near the dataclass decorator
3907        if let Some(class_match) = Regex::new(r"class\s+(\w+)").unwrap().find(content) {
3908            if let Some(captures) = Regex::new(r"class\s+(\w+)")
3909                .unwrap()
3910                .captures(class_match.as_str())
3911            {
3912                return captures.get(1).unwrap().as_str().to_string();
3913            }
3914        }
3915        "UnknownClass".to_string()
3916    }
3917
3918    fn analyze_dataclass_fields(&self, content: &str, class_name: &str) -> Vec<DataclassField> {
3919        // Simplified field analysis - in production this would parse the class body
3920        let mut fields = Vec::new();
3921
3922        // Look for field annotations in the class
3923        let field_regex = Regex::new(&format!(r"class\s+{class_name}.*?(\w+):\s*(\w+)")).unwrap();
3924        for captures in field_regex.captures_iter(content) {
3925            if captures.len() >= 3 {
3926                let field_name = captures.get(1).unwrap().as_str().to_string();
3927                let field_type = captures.get(2).unwrap().as_str().to_string();
3928
3929                fields.push(DataclassField {
3930                    name: field_name,
3931                    field_type,
3932                    has_default: false,
3933                    is_optional: false,
3934                    validation_rules: Vec::new(),
3935                    metadata: Vec::new(),
3936                });
3937            }
3938        }
3939
3940        fields
3941    }
3942
3943    fn detect_dataclass_features(&self, content: &str, _class_name: &str) -> Vec<DataclassFeature> {
3944        let mut features = Vec::new();
3945
3946        if content.contains("frozen=True") {
3947            features.push(DataclassFeature::FrozenClass);
3948        }
3949        if content.contains("__slots__") {
3950            features.push(DataclassFeature::SlotsUsage);
3951        }
3952        if content.contains("__post_init__") {
3953            features.push(DataclassFeature::PostInitProcessing);
3954        }
3955        if content.contains("default_factory") {
3956            features.push(DataclassFeature::FieldFactories);
3957        }
3958
3959        features
3960    }
3961
3962    fn assess_dataclass_complexity(
3963        &self,
3964        fields: &[DataclassField],
3965        features: &[DataclassFeature],
3966    ) -> FeatureComplexity {
3967        let complexity_score = fields.len() + features.len() * 2;
3968
3969        match complexity_score {
3970            0..=3 => FeatureComplexity::Simple,
3971            4..=8 => FeatureComplexity::Moderate,
3972            9..=15 => FeatureComplexity::Complex,
3973            _ => FeatureComplexity::Expert,
3974        }
3975    }
3976
3977    fn score_dataclass_best_practices(
3978        &self,
3979        _fields: &[DataclassField],
3980        features: &[DataclassFeature],
3981    ) -> i32 {
3982        let mut score = 60; // Base score
3983
3984        // Add points for good practices
3985        if features.contains(&DataclassFeature::FrozenClass) {
3986            score += 15; // Immutability is good
3987        }
3988        if features.contains(&DataclassFeature::SlotsUsage) {
3989            score += 10; // Memory optimization
3990        }
3991        if features.contains(&DataclassFeature::PostInitProcessing) {
3992            score += 10; // Proper initialization
3993        }
3994
3995        score.min(100)
3996    }
3997
3998    fn get_dataclass_recommendations(
3999        &self,
4000        features: &[DataclassFeature],
4001        score: i32,
4002    ) -> Vec<String> {
4003        let mut recommendations = Vec::new();
4004
4005        if score < 70 {
4006            recommendations.push("Consider using dataclass best practices".to_string());
4007        }
4008
4009        if !features.contains(&DataclassFeature::SlotsUsage) {
4010            recommendations.push("Consider using __slots__ for memory optimization".to_string());
4011        }
4012
4013        if !features.contains(&DataclassFeature::FrozenClass) {
4014            recommendations.push("Consider making dataclass frozen for immutability".to_string());
4015        }
4016
4017        recommendations
4018    }
4019
4020    /// Calculate overall modernity score
4021    #[allow(clippy::too_many_arguments)] // Complex analysis requires multiple feature sets
4022    fn calculate_modernity_score(
4023        &self,
4024        dataclass_features: &[DataclassInfo],
4025        context_manager_features: &[ContextManagerInfo],
4026        fstring_features: &[FStringInfo],
4027        pattern_matching_features: &[PatternMatchingInfo],
4028        generator_features: &[GeneratorInfo],
4029        decorator_features: &[ModernDecoratorInfo],
4030        modern_syntax_features: &[ModernSyntaxInfo],
4031    ) -> i32 {
4032        let mut score = 50i32; // Base score
4033
4034        // Add points for modern features
4035        score += (dataclass_features.len() * 8).min(20) as i32;
4036        score += (context_manager_features.len() * 5).min(15) as i32;
4037        score += (fstring_features.len() * 3).min(10) as i32;
4038        score += (pattern_matching_features.len() * 10).min(20) as i32;
4039        score += (generator_features.len() * 4).min(12) as i32;
4040        score += (decorator_features.len() * 2).min(10) as i32;
4041        score += (modern_syntax_features.len() * 3).min(13) as i32;
4042
4043        score.min(100)
4044    }
4045
4046    /// Generate modern feature recommendations
4047    #[allow(clippy::too_many_arguments)] // Complex analysis requires multiple feature sets
4048    fn get_modern_feature_recommendations(
4049        &self,
4050        dataclass_features: &[DataclassInfo],
4051        context_manager_features: &[ContextManagerInfo],
4052        fstring_features: &[FStringInfo],
4053        _pattern_matching_features: &[PatternMatchingInfo],
4054        generator_features: &[GeneratorInfo],
4055        _decorator_features: &[ModernDecoratorInfo],
4056        modern_syntax_features: &[ModernSyntaxInfo],
4057        python_version: &PythonVersionDetected,
4058    ) -> Vec<String> {
4059        let mut recommendations = Vec::new();
4060
4061        if dataclass_features.is_empty() {
4062            recommendations.push(
4063                "Consider using @dataclass for data classes instead of manual __init__".to_string(),
4064            );
4065        }
4066
4067        if context_manager_features.is_empty() {
4068            recommendations
4069                .push("Use context managers (with statements) for resource management".to_string());
4070        }
4071
4072        if fstring_features.is_empty() {
4073            recommendations.push(
4074                "Consider using f-strings for string formatting instead of .format()".to_string(),
4075            );
4076        }
4077
4078        if generator_features.is_empty() {
4079            recommendations
4080                .push("Consider using generators for memory-efficient iteration".to_string());
4081        }
4082
4083        // Version-specific recommendations
4084        if self.is_version_supported("3.10", &python_version.minimum_version) {
4085            recommendations.push(
4086                "Consider using pattern matching (match/case) for complex conditionals".to_string(),
4087            );
4088        }
4089
4090        if self.is_version_supported("3.8", &python_version.minimum_version) {
4091            let has_walrus = modern_syntax_features
4092                .iter()
4093                .any(|f| matches!(f.feature_type, ModernSyntaxType::WalrusOperator));
4094            if !has_walrus {
4095                recommendations.push(
4096                    "Consider using walrus operator (:=) for assignment expressions".to_string(),
4097                );
4098            }
4099        }
4100
4101        recommendations
4102    }
4103
4104    /// Analyze context usage pattern
4105    fn analyze_context_usage_pattern(
4106        &self,
4107        content: &str,
4108        _context_match: &str,
4109    ) -> ContextUsagePattern {
4110        if content.contains("async with") {
4111            ContextUsagePattern::AsyncContext
4112        } else if content.matches("with").count() > 1 {
4113            ContextUsagePattern::MultipleContexts
4114        } else {
4115            ContextUsagePattern::SingleContext
4116        }
4117    }
4118
4119    /// Assess resource management quality
4120    fn assess_resource_management_quality(
4121        &self,
4122        content: &str,
4123        _context_match: &str,
4124    ) -> ResourceManagementQuality {
4125        let has_error_handling = content.contains("try") || content.contains("except");
4126        let has_finally = content.contains("finally");
4127        let has_proper_cleanup = content.contains("close()") || content.contains("__exit__");
4128
4129        match (has_error_handling, has_finally, has_proper_cleanup) {
4130            (true, true, true) => ResourceManagementQuality::Excellent,
4131            (true, _, true) => ResourceManagementQuality::Good,
4132            (true, _, _) => ResourceManagementQuality::Adequate,
4133            (false, _, true) => ResourceManagementQuality::Poor,
4134            _ => ResourceManagementQuality::Dangerous,
4135        }
4136    }
4137
4138    /// Assess context error handling
4139    fn assess_context_error_handling(
4140        &self,
4141        content: &str,
4142        _context_match: &str,
4143    ) -> ContextErrorHandling {
4144        if content.contains("except") && content.contains("finally") {
4145            ContextErrorHandling::Comprehensive
4146        } else if content.contains("except") {
4147            ContextErrorHandling::Basic
4148        } else if content.contains("try") {
4149            ContextErrorHandling::Minimal
4150        } else {
4151            ContextErrorHandling::None
4152        }
4153    }
4154
4155    /// Calculate context nesting level
4156    fn calculate_context_nesting_level(&self, content: &str, _context_match: &str) -> usize {
4157        // Count actual with statement patterns
4158        let with_pattern = Regex::new(r"\bwith\s+[^:]+:").unwrap();
4159        let with_count = with_pattern.find_iter(content).count();
4160        if with_count > 3 {
4161            3 // Cap at 3 for simplicity
4162        } else {
4163            with_count
4164        }
4165    }
4166
4167    /// Check context best practices
4168    fn check_context_best_practices(&self, content: &str, _context_match: &str) -> bool {
4169        // Check for good practices
4170        let has_appropriate_error_handling = content.contains("except");
4171        let not_overly_nested = self.calculate_context_nesting_level(content, _context_match) <= 2;
4172        let has_resource_cleanup = content.contains("close") || content.contains("__exit__");
4173
4174        has_appropriate_error_handling && not_overly_nested && has_resource_cleanup
4175    }
4176
4177    /// Helper methods for f-string analysis
4178    fn assess_fstring_complexity(&self, expression: &str) -> FStringComplexity {
4179        // Count actual f-string expression braces
4180        let brace_pattern = Regex::new(r"\{[^}]+\}").unwrap();
4181        let brace_count = brace_pattern.find_iter(expression).count();
4182        let has_function_calls = expression.contains('(');
4183        let has_format_spec = expression.contains(':');
4184
4185        match (brace_count, has_function_calls, has_format_spec) {
4186            (1, false, false) => FStringComplexity::Simple,
4187            (1..=2, _, true) | (1..=2, true, _) => FStringComplexity::Moderate,
4188            (3..=5, _, _) => FStringComplexity::Complex,
4189            _ => FStringComplexity::Advanced,
4190        }
4191    }
4192
4193    fn detect_fstring_features(&self, expression: &str) -> Vec<FStringFeature> {
4194        let mut features = Vec::new();
4195
4196        if expression.contains('{') && expression.contains('}') {
4197            features.push(FStringFeature::BasicInterpolation);
4198        }
4199        if expression.contains('(') {
4200            features.push(FStringFeature::ExpressionEvaluation);
4201        }
4202        if expression.contains(':') {
4203            features.push(FStringFeature::FormatSpecifiers);
4204        }
4205        if expression.contains('!') {
4206            features.push(FStringFeature::ConversionFlags);
4207        }
4208        if expression.starts_with("rf") || expression.starts_with("fr") {
4209            features.push(FStringFeature::RawFString);
4210        }
4211
4212        features
4213    }
4214
4215    fn assess_fstring_performance(
4216        &self,
4217        _expression: &str,
4218        features: &[FStringFeature],
4219    ) -> PerformanceImpact {
4220        if features.contains(&FStringFeature::ComplexExpressions) {
4221            PerformanceImpact::Negative
4222        } else if features.contains(&FStringFeature::ExpressionEvaluation) {
4223            PerformanceImpact::Neutral
4224        } else {
4225            PerformanceImpact::Positive
4226        }
4227    }
4228
4229    fn assess_formatting_quality(&self, expression: &str) -> FormattingQuality {
4230        let length = expression.len();
4231        let complexity = self.assess_fstring_complexity(expression);
4232
4233        match (length, complexity) {
4234            (0..=50, FStringComplexity::Simple) => FormattingQuality::Excellent,
4235            (0..=100, FStringComplexity::Moderate) => FormattingQuality::Good,
4236            (0..=150, FStringComplexity::Complex) => FormattingQuality::Adequate,
4237            (0..=200, _) => FormattingQuality::Poor,
4238            _ => FormattingQuality::Unreadable,
4239        }
4240    }
4241
4242    fn calculate_fstring_readability(&self, expression: &str) -> i32 {
4243        let mut score = 100;
4244
4245        if expression.len() > 100 {
4246            score -= 20;
4247        }
4248        if expression.matches('{').count() > 3 {
4249            score -= 15;
4250        }
4251        if expression.contains("()") {
4252            score -= 10;
4253        }
4254
4255        score.max(0)
4256    }
4257
4258    /// Version comparison helper
4259    fn is_newer_version(&self, version1: &str, version2: &str) -> bool {
4260        // Simple version comparison (would be more sophisticated in production)
4261        let v1 = version1.trim_end_matches('+');
4262        let v2 = version2.trim_end_matches('+');
4263        v1 > v2
4264    }
4265
4266    fn is_version_supported(&self, required: &str, current: &str) -> bool {
4267        // Check if current version supports the required version
4268        self.is_newer_version(current, required) || current == required
4269    }
4270
4271    /// Pattern matching helper methods
4272    fn analyze_match_patterns(&self, match_statement: &str) -> Vec<PatternType> {
4273        let mut patterns = Vec::new();
4274
4275        if match_statement.contains("case _:") {
4276            patterns.push(PatternType::WildcardPattern);
4277        }
4278        if match_statement.contains("case ") && match_statement.contains("if ") {
4279            patterns.push(PatternType::GuardedPattern);
4280        }
4281        if match_statement.contains("case [") {
4282            patterns.push(PatternType::SequencePattern);
4283        }
4284        if match_statement.contains("case {") {
4285            patterns.push(PatternType::MappingPattern);
4286        }
4287        if match_statement.contains(" | ") {
4288            patterns.push(PatternType::OrPattern);
4289        }
4290
4291        if patterns.is_empty() {
4292            patterns.push(PatternType::LiteralPattern);
4293        }
4294
4295        patterns
4296    }
4297
4298    fn assess_pattern_complexity(&self, patterns: &[PatternType]) -> PatternComplexity {
4299        let complexity_score = patterns.len()
4300            + patterns
4301                .iter()
4302                .map(|p| match p {
4303                    PatternType::GuardedPattern => 3,
4304                    PatternType::SequencePattern | PatternType::MappingPattern => 2,
4305                    PatternType::OrPattern => 2,
4306                    _ => 1,
4307                })
4308                .sum::<usize>();
4309
4310        match complexity_score {
4311            0..=3 => PatternComplexity::Simple,
4312            4..=8 => PatternComplexity::Moderate,
4313            9..=15 => PatternComplexity::Complex,
4314            _ => PatternComplexity::Advanced,
4315        }
4316    }
4317
4318    fn check_pattern_exhaustiveness(&self, match_statement: &str) -> bool {
4319        match_statement.contains("case _:") || match_statement.contains("case default:")
4320    }
4321
4322    fn assess_match_performance(
4323        &self,
4324        patterns: &[PatternType],
4325        _match_statement: &str,
4326    ) -> MatchPerformance {
4327        let has_complex_patterns = patterns.iter().any(|p| {
4328            matches!(
4329                p,
4330                PatternType::GuardedPattern
4331                    | PatternType::SequencePattern
4332                    | PatternType::MappingPattern
4333            )
4334        });
4335
4336        if has_complex_patterns && patterns.len() > 10 {
4337            MatchPerformance::Poor
4338        } else if has_complex_patterns {
4339            MatchPerformance::Fair
4340        } else if patterns.len() <= 5 {
4341            MatchPerformance::Optimal
4342        } else {
4343            MatchPerformance::Good
4344        }
4345    }
4346
4347    fn score_pattern_best_practices(
4348        &self,
4349        patterns: &[PatternType],
4350        has_guards: bool,
4351        is_exhaustive: bool,
4352    ) -> i32 {
4353        let mut score = 70;
4354
4355        if is_exhaustive {
4356            score += 20;
4357        }
4358        if has_guards {
4359            score += 10; // Guards can be good for complex logic
4360        }
4361        if patterns.len() <= 5 {
4362            score += 10; // Simple patterns are better
4363        }
4364
4365        score.min(100)
4366    }
4367
4368    /// Generator helper methods
4369    fn classify_generator_usage_pattern(
4370        &self,
4371        content: &str,
4372        _generator_match: &str,
4373    ) -> GeneratorUsagePattern {
4374        if content.contains("yield from") {
4375            GeneratorUsagePattern::Pipeline
4376        } else if content.contains("while True") {
4377            GeneratorUsagePattern::InfiniteSequence
4378        } else if content.contains("map") || content.contains("filter") {
4379            GeneratorUsagePattern::DataTransformation
4380        } else {
4381            GeneratorUsagePattern::SimpleIteration
4382        }
4383    }
4384
4385    fn assess_generator_memory_efficiency(
4386        &self,
4387        content: &str,
4388        _generator_match: &str,
4389    ) -> MemoryEfficiency {
4390        let has_large_data_structures =
4391            content.contains("list(") || content.contains("[") && content.len() > 100;
4392        let uses_yield_properly = content.contains("yield") && !content.contains("return [");
4393
4394        match (uses_yield_properly, has_large_data_structures) {
4395            (true, false) => MemoryEfficiency::Excellent,
4396            (true, true) => MemoryEfficiency::Good,
4397            (false, false) => MemoryEfficiency::Adequate,
4398            (false, true) => MemoryEfficiency::Poor,
4399        }
4400    }
4401
4402    fn assess_generator_complexity(
4403        &self,
4404        content: &str,
4405        _generator_match: &str,
4406    ) -> GeneratorComplexity {
4407        // Count actual yield statements with proper pattern matching
4408        let yield_pattern = Regex::new(r"\byield\s+").unwrap();
4409        let yield_count = yield_pattern.find_iter(content).count();
4410        let has_complex_logic = content.contains("if") && content.contains("for");
4411        // Count actual for loops
4412        let for_pattern = Regex::new(r"\bfor\s+\w+\s+in\s+").unwrap();
4413        let has_nested_loops = for_pattern.find_iter(content).count() > 1;
4414
4415        match (yield_count, has_complex_logic, has_nested_loops) {
4416            (1, false, false) => GeneratorComplexity::Simple,
4417            (1..=3, _, false) => GeneratorComplexity::Moderate,
4418            (_, true, true) => GeneratorComplexity::Advanced,
4419            _ => GeneratorComplexity::Complex,
4420        }
4421    }
4422
4423    fn analyze_yield_usage(&self, content: &str, _generator_match: &str) -> YieldAnalysis {
4424        // Count actual yield statements
4425        let yield_pattern = Regex::new(r"\byield\s+").unwrap();
4426        YieldAnalysis {
4427            yield_count: yield_pattern.find_iter(content).count(),
4428            has_yield_from: content.contains("yield from"),
4429            has_send_values: content.contains(".send("),
4430            has_throw_values: content.contains(".throw("),
4431            has_close_handling: content.contains(".close("),
4432        }
4433    }
4434
4435    fn identify_generator_optimizations(
4436        &self,
4437        content: &str,
4438        _generator_match: &str,
4439    ) -> Vec<String> {
4440        let mut optimizations = Vec::new();
4441
4442        if content.contains("list(") && content.contains("yield") {
4443            optimizations.push("Avoid converting generator to list unless necessary".to_string());
4444        }
4445
4446        if content.matches("for").count() > 2 {
4447            optimizations
4448                .push("Consider breaking complex generator into smaller functions".to_string());
4449        }
4450
4451        if !content.contains("yield from") && content.contains("for") && content.contains("yield") {
4452            optimizations
4453                .push("Consider using 'yield from' for delegating to sub-generators".to_string());
4454        }
4455
4456        optimizations
4457    }
4458
4459    /// Decorator helper methods
4460    fn classify_decorator_category(&self, decorator_name: &str) -> DecoratorCategory {
4461        match decorator_name {
4462            "property" | "staticmethod" | "classmethod" => DecoratorCategory::BuiltIn,
4463            "wraps" | "singledispatch" | "cache" | "lru_cache" => {
4464                DecoratorCategory::FunctoolsDecorator
4465            }
4466            "app.route" | "api.route" | "route" => DecoratorCategory::WebFramework,
4467            "pytest.fixture" | "pytest.mark" | "unittest.mock" => DecoratorCategory::Testing,
4468            "dataclass" | "validator" => DecoratorCategory::DataValidation,
4469            _ => DecoratorCategory::Custom,
4470        }
4471    }
4472
4473    fn analyze_decorator_usage_pattern(
4474        &self,
4475        content: &str,
4476        decorator: &str,
4477    ) -> DecoratorUsagePattern {
4478        let decorator_context = self.get_decorator_context(content, decorator);
4479
4480        if decorator_context.contains('@') && decorator_context.matches('@').count() > 1 {
4481            DecoratorUsagePattern::StackedDecorators
4482        } else if decorator.contains('(') {
4483            DecoratorUsagePattern::ParameterizedDecorator
4484        } else {
4485            DecoratorUsagePattern::SingleDecorator
4486        }
4487    }
4488
4489    fn get_decorator_context(&self, content: &str, decorator: &str) -> String {
4490        // Get surrounding context for the decorator
4491        if let Some(pos) = content.find(decorator) {
4492            let start = pos.saturating_sub(100);
4493            let end = (pos + decorator.len() + 100).min(content.len());
4494            content[start..end].to_string()
4495        } else {
4496            decorator.to_string()
4497        }
4498    }
4499
4500    fn assess_decorator_complexity(&self, decorator: &str) -> DecoratorComplexity {
4501        if decorator.contains('(') && decorator.contains(',') {
4502            DecoratorComplexity::Complex
4503        } else if decorator.contains('(') {
4504            DecoratorComplexity::Moderate
4505        } else {
4506            DecoratorComplexity::Simple
4507        }
4508    }
4509
4510    fn score_decorator_best_practices(
4511        &self,
4512        category: &DecoratorCategory,
4513        usage_pattern: &DecoratorUsagePattern,
4514    ) -> i32 {
4515        let mut score = 80;
4516
4517        match category {
4518            DecoratorCategory::BuiltIn => score += 10,
4519            DecoratorCategory::FunctoolsDecorator => score += 15,
4520            DecoratorCategory::Performance => score += 10,
4521            _ => {}
4522        }
4523
4524        match usage_pattern {
4525            DecoratorUsagePattern::SingleDecorator => score += 5,
4526            DecoratorUsagePattern::StackedDecorators => score -= 5, // Can be complex
4527            _ => {}
4528        }
4529
4530        score.min(100)
4531    }
4532
4533    /// Modern syntax helper methods
4534    fn assess_syntax_complexity(&self, content: &str, pattern: &Regex) -> SyntaxComplexity {
4535        let usage_count = pattern.find_iter(content).count();
4536        let total_lines = content.lines().count();
4537        let usage_density = if total_lines > 0 {
4538            usage_count as f32 / total_lines as f32
4539        } else {
4540            0.0
4541        };
4542
4543        match usage_density {
4544            d if d > 0.1 => SyntaxComplexity::Expert,
4545            d if d > 0.05 => SyntaxComplexity::Complex,
4546            d if d > 0.01 => SyntaxComplexity::Moderate,
4547            _ => SyntaxComplexity::Simple,
4548        }
4549    }
4550
4551    fn check_syntax_best_practices(&self, content: &str, feature_type: &ModernSyntaxType) -> bool {
4552        match feature_type {
4553            ModernSyntaxType::WalrusOperator => {
4554                // Check if walrus operator is used appropriately (not overused)
4555                content.matches(":=").count() <= content.lines().count() / 10
4556            }
4557            ModernSyntaxType::PositionalOnlyParams => {
4558                // Check if positional-only parameters are used with good reason
4559                content.contains("def ") && content.contains("/")
4560            }
4561            ModernSyntaxType::TypeUnionOperator => {
4562                // Check if union operator is used instead of typing.Union
4563                !content.contains("typing.Union") || content.contains(" | ")
4564            }
4565            _ => true, // Default to good practices for other features
4566        }
4567    }
4568
4569    fn get_syntax_migration_suggestions(
4570        &self,
4571        feature_type: &ModernSyntaxType,
4572        usage_count: usize,
4573    ) -> Vec<String> {
4574        let mut suggestions = Vec::new();
4575
4576        match feature_type {
4577            ModernSyntaxType::WalrusOperator => {
4578                if usage_count > 10 {
4579                    suggestions.push(
4580                        "Consider if all walrus operator usages improve readability".to_string(),
4581                    );
4582                }
4583                suggestions.push(
4584                    "Use walrus operator to reduce code duplication in conditions".to_string(),
4585                );
4586            }
4587            ModernSyntaxType::GenericTypeHints => {
4588                suggestions.push(
4589                    "Migrate from typing.List/Dict to built-in list/dict for type hints"
4590                        .to_string(),
4591                );
4592            }
4593            ModernSyntaxType::TypeUnionOperator => {
4594                suggestions.push(
4595                    "Replace typing.Union with | operator for cleaner type hints".to_string(),
4596                );
4597            }
4598            _ => {}
4599        }
4600
4601        suggestions
4602    }
4603
4604    /// Analyze async functions in detail
4605    fn analyze_async_functions(&self, content: &str, async_functions: &mut Vec<AsyncFunctionInfo>) {
4606        for patterns in self.async_patterns.values() {
4607            for pattern in patterns {
4608                if pattern.pattern_type == "function"
4609                    || pattern.pattern_type == "generator"
4610                    || pattern.pattern_type == "context_manager"
4611                    || pattern.pattern_type == "iterator"
4612                {
4613                    for captures in pattern.pattern.captures_iter(content) {
4614                        let full_match = captures.get(0).unwrap().as_str();
4615                        let function_name = captures
4616                            .get(1)
4617                            .map(|m| m.as_str().to_string())
4618                            .unwrap_or_else(|| "anonymous".to_string());
4619
4620                        let function_type =
4621                            self.determine_async_function_type(&pattern.name, full_match);
4622                        let complexity = self.assess_async_complexity(content, full_match);
4623                        let coroutine_type = self.classify_coroutine_type(content);
4624                        let error_handling = self.assess_error_handling(content, full_match);
4625                        let has_timeout = self.has_timeout_handling(content, full_match);
4626                        let uses_context_manager =
4627                            self.uses_async_context_manager(content, full_match);
4628
4629                        async_functions.push(AsyncFunctionInfo {
4630                            name: function_name,
4631                            function_type,
4632                            complexity,
4633                            coroutine_type,
4634                            error_handling,
4635                            has_timeout,
4636                            uses_context_manager,
4637                            location: full_match.to_string(),
4638                        });
4639                    }
4640                }
4641            }
4642        }
4643    }
4644
4645    /// Analyze await usage patterns
4646    fn analyze_await_usage(&self, content: &str, await_patterns: &mut Vec<AwaitUsageInfo>) {
4647        let await_pattern = Regex::new(r"await\s+([^;\n]+)").unwrap();
4648
4649        for captures in await_pattern.captures_iter(content) {
4650            let full_match = captures.get(0).unwrap().as_str();
4651            let await_expr = captures.get(1).unwrap().as_str();
4652
4653            let context = self.determine_await_context(content, full_match);
4654            let usage_pattern = self.classify_await_usage_pattern(content, await_expr);
4655            let is_valid = self.validate_await_usage(&context);
4656            let potential_issues = self.detect_await_issues(content, await_expr, &context);
4657
4658            await_patterns.push(AwaitUsageInfo {
4659                location: full_match.to_string(),
4660                context,
4661                usage_pattern,
4662                is_valid,
4663                potential_issues,
4664            });
4665        }
4666    }
4667
4668    /// Analyze concurrency patterns
4669    fn analyze_concurrency_patterns(
4670        &self,
4671        content: &str,
4672        concurrency_patterns: &mut Vec<ConcurrencyPatternInfo>,
4673    ) {
4674        for patterns in self.async_patterns.values() {
4675            for pattern in patterns {
4676                if pattern.pattern_type == "concurrency" {
4677                    for captures in pattern.pattern.captures_iter(content) {
4678                        let full_match = captures.get(0).unwrap().as_str();
4679
4680                        let pattern_type = self.map_to_concurrency_pattern_type(&pattern.name);
4681                        let usage_quality =
4682                            self.assess_concurrency_usage_quality(content, full_match);
4683                        let best_practices_followed =
4684                            self.check_concurrency_best_practices(content, full_match);
4685
4686                        concurrency_patterns.push(ConcurrencyPatternInfo {
4687                            pattern_type,
4688                            usage_quality,
4689                            performance_impact: pattern.performance_impact.clone(),
4690                            location: full_match.to_string(),
4691                            best_practices_followed,
4692                        });
4693                    }
4694                }
4695            }
4696        }
4697    }
4698
4699    /// Detect async performance issues
4700    fn detect_async_performance_issues(
4701        &self,
4702        content: &str,
4703        issues: &mut Vec<AsyncPerformanceIssue>,
4704    ) {
4705        // Detect blocking IO in async functions - look for blocking calls within async function bodies
4706        if content.contains("async def")
4707            && (content.contains("time.sleep")
4708                || content.contains("open(")
4709                || content.contains("input("))
4710        {
4711            issues.push(AsyncPerformanceIssue {
4712                issue_type: AsyncPerformanceIssueType::BlockingIOInAsync,
4713                severity: AsyncIssueSeverity::High,
4714                location: "Async function with blocking operations".to_string(),
4715                description: "Blocking I/O operation in async function".to_string(),
4716                recommendation: "Use async I/O operations or run_in_executor".to_string(),
4717                estimated_impact: AsyncPerformanceImpact::Critical,
4718            });
4719        }
4720
4721        // Detect await in loops
4722        let await_loop_pattern = Regex::new(r"for\s+.*?:\s*.*?await\s+").unwrap();
4723        for captures in await_loop_pattern.captures_iter(content) {
4724            let full_match = captures.get(0).unwrap().as_str();
4725            issues.push(AsyncPerformanceIssue {
4726                issue_type: AsyncPerformanceIssueType::AwaitInLoop,
4727                severity: AsyncIssueSeverity::Medium,
4728                location: full_match.to_string(),
4729                description: "Sequential await in loop - consider asyncio.gather()".to_string(),
4730                recommendation:
4731                    "Use asyncio.gather() or asyncio.as_completed() for concurrent execution"
4732                        .to_string(),
4733                estimated_impact: AsyncPerformanceImpact::Negative,
4734            });
4735        }
4736
4737        // Detect missing concurrency opportunities
4738        let sequential_await_pattern = Regex::new(r"await\s+\w+.*\n.*await\s+\w+").unwrap();
4739        for captures in sequential_await_pattern.captures_iter(content) {
4740            let full_match = captures.get(0).unwrap().as_str();
4741            issues.push(AsyncPerformanceIssue {
4742                issue_type: AsyncPerformanceIssueType::MissingConcurrency,
4743                severity: AsyncIssueSeverity::Medium,
4744                location: full_match.to_string(),
4745                description: "Sequential await calls could be concurrent".to_string(),
4746                recommendation: "Consider using asyncio.gather() for independent operations"
4747                    .to_string(),
4748                estimated_impact: AsyncPerformanceImpact::Negative,
4749            });
4750        }
4751    }
4752
4753    /// Detect async security issues
4754    fn detect_async_security_issues(&self, content: &str, issues: &mut Vec<AsyncSecurityIssue>) {
4755        // Detect missing timeouts
4756        let await_pattern = Regex::new(r"await\s+").unwrap();
4757        // Count actual timeout function calls with proper pattern matching
4758        let wait_for_pattern = Regex::new(r"\basyncio\.wait_for\s*\(").unwrap();
4759        let timeout_pattern = Regex::new(r"\basyncio\.timeout\s*\(").unwrap();
4760        let timeout_count = wait_for_pattern.find_iter(content).count()
4761            + timeout_pattern.find_iter(content).count();
4762        let await_count = await_pattern.find_iter(content).count();
4763
4764        if await_count > timeout_count + 2 {
4765            issues.push(AsyncSecurityIssue {
4766                issue_type: AsyncSecurityIssueType::AsyncTimeoutVuln,
4767                severity: AsyncSecuritySeverity::Medium,
4768                location: "Multiple async operations".to_string(),
4769                description: "Missing timeout handling in async operations".to_string(),
4770                recommendation: "Add timeouts to prevent DoS attacks".to_string(),
4771            });
4772        }
4773
4774        // Detect shared state without locking
4775        let shared_state_pattern =
4776            Regex::new(r"(?:global|class)\s+\w+.*=.*\n.*async\s+def.*\w+.*=").unwrap();
4777        for captures in shared_state_pattern.captures_iter(content) {
4778            let full_match = captures.get(0).unwrap().as_str();
4779            if !content.contains("asyncio.Lock") && !content.contains("asyncio.Semaphore") {
4780                issues.push(AsyncSecurityIssue {
4781                    issue_type: AsyncSecurityIssueType::SharedStateNoLock,
4782                    severity: AsyncSecuritySeverity::High,
4783                    location: full_match.to_string(),
4784                    description: "Shared mutable state without proper locking".to_string(),
4785                    recommendation: "Use asyncio.Lock or asyncio.Semaphore for thread safety"
4786                        .to_string(),
4787                });
4788            }
4789        }
4790
4791        // Detect race condition patterns
4792        if content.contains("asyncio.gather")
4793            && !content.contains("asyncio.Lock")
4794            && content.matches("=").count() > 3
4795        {
4796            issues.push(AsyncSecurityIssue {
4797                issue_type: AsyncSecurityIssueType::AsyncRaceCondition,
4798                severity: AsyncSecuritySeverity::Medium,
4799                location: "Concurrent operations".to_string(),
4800                description: "Potential race condition in concurrent operations".to_string(),
4801                recommendation: "Review shared resource access and add synchronization".to_string(),
4802            });
4803        }
4804    }
4805
4806    /// Detect modern async features
4807    fn detect_modern_async_features(&self, content: &str, features: &mut Vec<ModernAsyncFeature>) {
4808        let modern_patterns = &[
4809            (
4810                "async with",
4811                ModernAsyncFeatureType::AsyncContextManager,
4812                "3.7+",
4813            ),
4814            (
4815                "asyncio.TaskGroup",
4816                ModernAsyncFeatureType::TaskGroups,
4817                "3.11+",
4818            ),
4819            (
4820                "asyncio.timeout",
4821                ModernAsyncFeatureType::AsyncioTimeout,
4822                "3.11+",
4823            ),
4824            ("async for", ModernAsyncFeatureType::AsyncIterators, "3.7+"),
4825            ("contextvars", ModernAsyncFeatureType::ContextVars, "3.7+"),
4826            ("asyncio.run", ModernAsyncFeatureType::AsyncioRun, "3.7+"),
4827        ];
4828
4829        for (pattern_str, feature_type, version) in modern_patterns {
4830            let count = content.matches(pattern_str).count();
4831            if count > 0 {
4832                features.push(ModernAsyncFeature {
4833                    feature_type: feature_type.clone(),
4834                    python_version: version.to_string(),
4835                    usage_count: count,
4836                    description: format!("Modern async feature: {pattern_str}"),
4837                    is_best_practice: true,
4838                });
4839            }
4840        }
4841
4842        // Detect async comprehensions
4843        let async_comp_pattern = Regex::new(r"\[.*async\s+for.*\]|\{.*async\s+for.*\}").unwrap();
4844        let comp_count = async_comp_pattern.find_iter(content).count();
4845        if comp_count > 0 {
4846            features.push(ModernAsyncFeature {
4847                feature_type: ModernAsyncFeatureType::AsyncComprehensions,
4848                python_version: "3.6+".to_string(),
4849                usage_count: comp_count,
4850                description: "Async comprehensions for concurrent iteration".to_string(),
4851                is_best_practice: true,
4852            });
4853        }
4854    }
4855
4856    /// Helper methods for async analysis
4857    fn determine_async_function_type(
4858        &self,
4859        pattern_name: &str,
4860        _full_match: &str,
4861    ) -> AsyncFunctionType {
4862        match pattern_name {
4863            "Async Function" => AsyncFunctionType::RegularAsync,
4864            "Async Generator" => AsyncFunctionType::AsyncGenerator,
4865            "Async Context Manager" => AsyncFunctionType::AsyncContextManager,
4866            "Async Iterator" => AsyncFunctionType::AsyncIterator,
4867            _ => AsyncFunctionType::RegularAsync,
4868        }
4869    }
4870
4871    fn assess_async_complexity(&self, _content: &str, function_match: &str) -> AsyncComplexity {
4872        // Count actual async patterns with proper parsing
4873        let await_pattern = Regex::new(r"\bawait\s+").unwrap();
4874        let try_pattern = Regex::new(r"\btry\s*:").unwrap();
4875        let gather_pattern = Regex::new(r"\basyncio\.gather\s*\(").unwrap();
4876
4877        let await_count = await_pattern.find_iter(function_match).count();
4878        let try_count = try_pattern.find_iter(function_match).count();
4879        let gather_count = gather_pattern.find_iter(function_match).count();
4880
4881        match (await_count, try_count, gather_count) {
4882            (0..=1, 0, 0) => AsyncComplexity::Simple,
4883            (2..=3, 0..=1, 0..=1) => AsyncComplexity::Moderate,
4884            (4..=6, 1..=2, 0..=2) => AsyncComplexity::Complex,
4885            _ => AsyncComplexity::Advanced,
4886        }
4887    }
4888
4889    fn classify_coroutine_type(&self, content: &str) -> CoroutineType {
4890        if content.contains("asyncio") {
4891            CoroutineType::Framework("asyncio".to_string())
4892        } else if content.contains("trio") {
4893            CoroutineType::Framework("trio".to_string())
4894        } else if content.contains("curio") {
4895            CoroutineType::Framework("curio".to_string())
4896        } else if content.contains("yield from") {
4897            CoroutineType::Generator
4898        } else {
4899            CoroutineType::Native
4900        }
4901    }
4902
4903    fn assess_error_handling(&self, _content: &str, function_match: &str) -> AsyncErrorHandling {
4904        if function_match.contains("asyncio.timeout") || function_match.contains("asyncio.wait_for")
4905        {
4906            AsyncErrorHandling::Robust
4907        } else if function_match.contains("timeout") {
4908            AsyncErrorHandling::Timeout
4909        } else if function_match.contains("try") && function_match.contains("except") {
4910            AsyncErrorHandling::Basic
4911        } else {
4912            AsyncErrorHandling::None
4913        }
4914    }
4915
4916    fn has_timeout_handling(&self, _content: &str, function_match: &str) -> bool {
4917        function_match.contains("timeout") || function_match.contains("asyncio.wait_for")
4918    }
4919
4920    fn uses_async_context_manager(&self, _content: &str, function_match: &str) -> bool {
4921        function_match.contains("async with")
4922    }
4923
4924    fn determine_await_context(&self, content: &str, await_match: &str) -> AwaitContext {
4925        // Simplified context detection - in practice, would need more sophisticated parsing
4926        if content.contains("async def") {
4927            if await_match.contains("__aenter__") || await_match.contains("__aexit__") {
4928                AwaitContext::AsyncContextManager
4929            } else if await_match.contains("__aiter__") || await_match.contains("__anext__") {
4930                AwaitContext::AsyncIterator
4931            } else if await_match.contains("yield") {
4932                AwaitContext::AsyncGenerator
4933            } else {
4934                AwaitContext::AsyncFunction
4935            }
4936        } else if await_match.contains("[") && await_match.contains("for") {
4937            AwaitContext::Comprehension
4938        } else if await_match.contains("lambda") {
4939            AwaitContext::Lambda
4940        } else {
4941            AwaitContext::SyncContext
4942        }
4943    }
4944
4945    fn classify_await_usage_pattern(&self, content: &str, await_expr: &str) -> AwaitUsagePattern {
4946        if content.contains("asyncio.gather") {
4947            AwaitUsagePattern::GatheredAwait
4948        } else if await_expr.contains("await") {
4949            AwaitUsagePattern::NestedAwait
4950        } else if content.contains("if") && await_expr.contains("await") {
4951            AwaitUsagePattern::ConditionalAwait
4952        } else if content.matches("await").count() > 1 {
4953            AwaitUsagePattern::SequentialAwaits
4954        } else {
4955            AwaitUsagePattern::SingleAwait
4956        }
4957    }
4958
4959    fn validate_await_usage(&self, context: &AwaitContext) -> bool {
4960        !matches!(
4961            context,
4962            AwaitContext::SyncContext | AwaitContext::Comprehension | AwaitContext::Lambda
4963        )
4964    }
4965
4966    fn detect_await_issues(
4967        &self,
4968        content: &str,
4969        await_expr: &str,
4970        context: &AwaitContext,
4971    ) -> Vec<AwaitIssue> {
4972        let mut issues = Vec::new();
4973
4974        if !self.validate_await_usage(context) {
4975            issues.push(AwaitIssue::IllegalContext);
4976        }
4977
4978        if await_expr.contains("open(") || await_expr.contains("input(") {
4979            issues.push(AwaitIssue::BlockingCall);
4980        }
4981
4982        if !content.contains("timeout") && !content.contains("asyncio.wait_for") {
4983            issues.push(AwaitIssue::TimeoutMissing);
4984        }
4985
4986        issues
4987    }
4988
4989    fn map_to_concurrency_pattern_type(&self, pattern_name: &str) -> ConcurrencyPatternType {
4990        match pattern_name {
4991            "Asyncio Gather" => ConcurrencyPatternType::AsyncioGather,
4992            "Asyncio Wait" => ConcurrencyPatternType::AsyncioWait,
4993            "Asyncio Queue" => ConcurrencyPatternType::AsyncioQueue,
4994            "Asyncio Semaphore" => ConcurrencyPatternType::AsyncioSemaphore,
4995            "Asyncio Lock" => ConcurrencyPatternType::AsyncioLock,
4996            "TaskGroup" => ConcurrencyPatternType::TaskGroup,
4997            "Concurrent Futures" => ConcurrencyPatternType::ConcurrentFutures,
4998            "Asyncio Timeout" => ConcurrencyPatternType::AsyncioTimeout,
4999            "Asyncio Event" => ConcurrencyPatternType::AsyncioEvent,
5000            "Asyncio Condition" => ConcurrencyPatternType::AsyncioCondition,
5001            _ => ConcurrencyPatternType::AsyncioGather,
5002        }
5003    }
5004
5005    fn assess_concurrency_usage_quality(
5006        &self,
5007        content: &str,
5008        pattern_match: &str,
5009    ) -> ConcurrencyUsageQuality {
5010        let has_error_handling = pattern_match.contains("try") || pattern_match.contains("except");
5011        let has_timeout = pattern_match.contains("timeout") || content.contains("asyncio.wait_for");
5012        let has_proper_cleanup =
5013            pattern_match.contains("finally") || pattern_match.contains("async with");
5014
5015        match (has_error_handling, has_timeout, has_proper_cleanup) {
5016            (true, true, true) => ConcurrencyUsageQuality::Excellent,
5017            (true, true, false) | (true, false, true) => ConcurrencyUsageQuality::Good,
5018            (true, false, false) | (false, true, false) | (false, true, true) => {
5019                ConcurrencyUsageQuality::Adequate
5020            }
5021            (false, false, true) => ConcurrencyUsageQuality::Poor,
5022            (false, false, false) => ConcurrencyUsageQuality::Dangerous,
5023        }
5024    }
5025
5026    fn check_concurrency_best_practices(&self, content: &str, _pattern_match: &str) -> bool {
5027        content.contains("async with")
5028            && (content.contains("timeout") || content.contains("asyncio.wait_for"))
5029            && content.contains("try")
5030    }
5031
5032    fn calculate_async_score(
5033        &self,
5034        async_functions: &[AsyncFunctionInfo],
5035        concurrency_patterns: &[ConcurrencyPatternInfo],
5036        performance_issues: &[AsyncPerformanceIssue],
5037        security_issues: &[AsyncSecurityIssue],
5038    ) -> i32 {
5039        let base_score = 50;
5040
5041        // Bonus for async functions
5042        let async_bonus = async_functions.len() as i32 * 5;
5043
5044        // Bonus for good concurrency patterns
5045        let concurrency_bonus = concurrency_patterns
5046            .iter()
5047            .map(|p| match p.usage_quality {
5048                ConcurrencyUsageQuality::Excellent => 10,
5049                ConcurrencyUsageQuality::Good => 7,
5050                ConcurrencyUsageQuality::Adequate => 4,
5051                ConcurrencyUsageQuality::Poor => 1,
5052                ConcurrencyUsageQuality::Dangerous => -5,
5053            })
5054            .sum::<i32>();
5055
5056        // Penalty for issues
5057        let performance_penalty = performance_issues
5058            .iter()
5059            .map(|i| match i.severity {
5060                AsyncIssueSeverity::Critical => 20,
5061                AsyncIssueSeverity::High => 15,
5062                AsyncIssueSeverity::Medium => 10,
5063                AsyncIssueSeverity::Low => 5,
5064                AsyncIssueSeverity::Info => 1,
5065            })
5066            .sum::<i32>();
5067
5068        let security_penalty = security_issues
5069            .iter()
5070            .map(|i| match i.severity {
5071                AsyncSecuritySeverity::Critical => 25,
5072                AsyncSecuritySeverity::High => 20,
5073                AsyncSecuritySeverity::Medium => 15,
5074                AsyncSecuritySeverity::Low => 10,
5075                AsyncSecuritySeverity::Info => 5,
5076            })
5077            .sum::<i32>();
5078
5079        (base_score + async_bonus + concurrency_bonus - performance_penalty - security_penalty)
5080            .clamp(0, 100)
5081    }
5082
5083    fn get_async_recommendations(
5084        &self,
5085        async_functions: &[AsyncFunctionInfo],
5086        await_patterns: &[AwaitUsageInfo],
5087        concurrency_patterns: &[ConcurrencyPatternInfo],
5088        performance_issues: &[AsyncPerformanceIssue],
5089        security_issues: &[AsyncSecurityIssue],
5090    ) -> Vec<String> {
5091        let mut recommendations = Vec::new();
5092
5093        if async_functions.is_empty() {
5094            recommendations.push("Consider using async/await for I/O bound operations".to_string());
5095        }
5096
5097        if !performance_issues.is_empty() {
5098            recommendations
5099                .push("Address async performance issues for better efficiency".to_string());
5100        }
5101
5102        if !security_issues.is_empty() {
5103            recommendations.push("Fix async security vulnerabilities".to_string());
5104        }
5105
5106        let has_poor_concurrency = concurrency_patterns.iter().any(|p| {
5107            matches!(
5108                p.usage_quality,
5109                ConcurrencyUsageQuality::Poor | ConcurrencyUsageQuality::Dangerous
5110            )
5111        });
5112
5113        if has_poor_concurrency {
5114            recommendations
5115                .push("Improve concurrency pattern usage with proper error handling".to_string());
5116        }
5117
5118        let has_invalid_await = await_patterns.iter().any(|p| !p.is_valid);
5119        if has_invalid_await {
5120            recommendations.push("Fix invalid await usage in sync contexts".to_string());
5121        }
5122
5123        let missing_timeouts = async_functions.iter().any(|f| !f.has_timeout);
5124        if missing_timeouts {
5125            recommendations.push("Add timeout handling to prevent hanging operations".to_string());
5126        }
5127
5128        recommendations
5129            .push("Use asyncio.gather() for concurrent independent operations".to_string());
5130        recommendations
5131            .push("Implement proper async context managers for resource cleanup".to_string());
5132        recommendations
5133            .push("Consider using Python 3.11+ TaskGroup for structured concurrency".to_string());
5134
5135        recommendations
5136    }
5137
5138    /// Helper methods for type hint analysis
5139    fn parse_type_hint_type(&self, hint_type: &str, captures: &regex::Captures) -> TypeHintType {
5140        match hint_type {
5141            "union" => {
5142                let types_str = captures.get(1).unwrap().as_str();
5143                let union_types = types_str.split(',').map(|s| s.trim().to_string()).collect();
5144                TypeHintType::UnionType(union_types)
5145            }
5146            "union_new" => {
5147                let type1 = captures.get(1).unwrap().as_str().to_string();
5148                let type2 = captures.get(2).unwrap().as_str().to_string();
5149                TypeHintType::UnionType(vec![type1, type2])
5150            }
5151            "optional" => {
5152                let inner_type = captures.get(1).unwrap().as_str().to_string();
5153                TypeHintType::OptionalType(inner_type)
5154            }
5155            "generic_list" => {
5156                let element_type = captures.get(1).unwrap().as_str().to_string();
5157                TypeHintType::GenericType(GenericTypeInfo {
5158                    base_type: "List".to_string(),
5159                    type_parameters: vec![element_type],
5160                    is_covariant: true,
5161                    is_contravariant: false,
5162                })
5163            }
5164            "generic_dict" => {
5165                let key_type = captures.get(1).unwrap().as_str().to_string();
5166                let value_type = captures.get(2).unwrap().as_str().to_string();
5167                TypeHintType::GenericType(GenericTypeInfo {
5168                    base_type: "Dict".to_string(),
5169                    type_parameters: vec![key_type, value_type],
5170                    is_covariant: false,
5171                    is_contravariant: false,
5172                })
5173            }
5174            "callable" => {
5175                let params_str = captures.get(1).unwrap().as_str();
5176                let return_type = captures.get(2).unwrap().as_str().to_string();
5177                let parameter_types = if params_str.is_empty() {
5178                    Vec::new()
5179                } else {
5180                    params_str
5181                        .split(',')
5182                        .map(|s| s.trim().to_string())
5183                        .collect()
5184                };
5185                TypeHintType::CallableType(CallableTypeInfo {
5186                    parameter_types,
5187                    return_type,
5188                    is_async: false,
5189                })
5190            }
5191            "typevar" => {
5192                let var_name = captures.get(1).unwrap().as_str().to_string();
5193                TypeHintType::TypeVarType(TypeVarInfo {
5194                    name: var_name,
5195                    bounds: Vec::new(),
5196                    constraints: Vec::new(),
5197                    covariant: false,
5198                    contravariant: false,
5199                })
5200            }
5201            "protocol" => TypeHintType::ProtocolType("Protocol".to_string()),
5202            "literal" => {
5203                let values_str = captures.get(1).unwrap().as_str();
5204                let literal_values = values_str
5205                    .split(',')
5206                    .map(|s| s.trim().to_string())
5207                    .collect();
5208                TypeHintType::LiteralType(literal_values)
5209            }
5210            "final" => {
5211                let final_type = captures.get(1).unwrap().as_str().to_string();
5212                TypeHintType::FinalType(final_type)
5213            }
5214            "typeddict" => {
5215                let class_name = captures.get(1).unwrap().as_str().to_string();
5216                TypeHintType::TypedDictType(TypedDictInfo {
5217                    name: class_name,
5218                    fields: Vec::new(), // Could use more parsing for fields
5219                    total: true,
5220                })
5221            }
5222            "generic_alias" => {
5223                let base_type = captures.get(1).unwrap().as_str().to_string();
5224                let element_type = captures.get(2).unwrap().as_str().to_string();
5225                TypeHintType::GenericType(GenericTypeInfo {
5226                    base_type,
5227                    type_parameters: vec![element_type],
5228                    is_covariant: true,
5229                    is_contravariant: false,
5230                })
5231            }
5232            _ => TypeHintType::SimpleType("Unknown".to_string()),
5233        }
5234    }
5235
5236    fn is_generic_type(&self, hint_type: &str) -> bool {
5237        matches!(hint_type, "generic_list" | "generic_dict" | "generic_alias")
5238    }
5239
5240    fn has_type_constraints(&self, hint_type: &str) -> bool {
5241        matches!(hint_type, "typevar" | "protocol" | "literal")
5242    }
5243
5244    fn get_modern_feature_type(&self, hint_type: &str) -> Option<ModernTypeFeatureType> {
5245        match hint_type {
5246            "union_new" => Some(ModernTypeFeatureType::UnionSyntaxPy310),
5247            "typeddict" => Some(ModernTypeFeatureType::TypedDict),
5248            "final" => Some(ModernTypeFeatureType::FinalType),
5249            "literal" => Some(ModernTypeFeatureType::LiteralType),
5250            "protocol" => Some(ModernTypeFeatureType::ProtocolType),
5251            "generic_alias" => Some(ModernTypeFeatureType::GenericAlias),
5252            _ => None,
5253        }
5254    }
5255
5256    fn detect_type_safety_issues(&self, content: &str, issues: &mut Vec<TypeSafetyIssue>) {
5257        // Detect Any type overuse
5258        // Count actual Any type usage with proper pattern
5259        let any_pattern = Regex::new(r"\bAny\b").unwrap();
5260        let any_count = any_pattern.find_iter(content).count();
5261        if any_count > 5 {
5262            issues.push(TypeSafetyIssue {
5263                issue_type: TypeSafetyIssueType::AnyTypeOveruse,
5264                severity: TypeSafetySeverity::Warning,
5265                location: "Multiple locations".to_string(),
5266                description: format!("Found {any_count} uses of Any type"),
5267                recommendation: "Consider using more specific type hints".to_string(),
5268            });
5269        }
5270
5271        // Detect missing type hints
5272        let func_pattern = Regex::new(r"def\s+\w+\s*\([^)]*\)\s*:").unwrap();
5273        let typed_func_pattern = Regex::new(r"def\s+\w+\s*\([^)]*\)\s*->\s*\w+:").unwrap();
5274
5275        let total_functions = func_pattern.find_iter(content).count();
5276        let typed_functions = typed_func_pattern.find_iter(content).count();
5277
5278        if total_functions > typed_functions && total_functions > 0 {
5279            let missing_hints = total_functions - typed_functions;
5280            issues.push(TypeSafetyIssue {
5281                issue_type: TypeSafetyIssueType::MissingTypeHints,
5282                severity: TypeSafetySeverity::Warning,
5283                location: "Function definitions".to_string(),
5284                description: format!("{missing_hints} functions missing return type hints"),
5285                recommendation: "Add return type annotations to functions".to_string(),
5286            });
5287        }
5288
5289        // Detect type: ignore overuse
5290        // Count actual type ignore comments with proper pattern
5291        let ignore_pattern = Regex::new(r"#\s*type:\s*ignore").unwrap();
5292        let ignore_count = ignore_pattern.find_iter(content).count();
5293        if ignore_count > 3 {
5294            issues.push(TypeSafetyIssue {
5295                issue_type: TypeSafetyIssueType::TypeIgnoreOveruse,
5296                severity: TypeSafetySeverity::Info,
5297                location: "Multiple locations".to_string(),
5298                description: format!("Found {ignore_count} type: ignore comments"),
5299                recommendation: "Review and fix type issues instead of ignoring them".to_string(),
5300            });
5301        }
5302
5303        // Detect deprecated typing syntax
5304        if content.contains("typing.List") || content.contains("typing.Dict") {
5305            issues.push(TypeSafetyIssue {
5306                issue_type: TypeSafetyIssueType::DeprecatedTypingSyntax,
5307                severity: TypeSafetySeverity::Info,
5308                location: "Import statements".to_string(),
5309                description: "Using deprecated typing imports".to_string(),
5310                recommendation: "Use built-in generics (list, dict) for Python 3.9+".to_string(),
5311            });
5312        }
5313    }
5314
5315    fn calculate_type_coverage(&self, content: &str, _type_hints: &[TypeHintInfo]) -> f32 {
5316        let func_pattern = Regex::new(r"def\s+\w+").unwrap();
5317        let total_functions = func_pattern.find_iter(content).count();
5318
5319        if total_functions == 0 {
5320            return 0.0;
5321        }
5322
5323        // Count functions with type annotations (parameter or return type hints)
5324        let typed_func_pattern =
5325            Regex::new(r"def\s+\w+\s*\([^)]*:\s*\w+|def\s+\w+\s*\([^)]*\)\s*->\s*\w+").unwrap();
5326        let typed_functions = typed_func_pattern.find_iter(content).count();
5327
5328        (typed_functions as f32 / total_functions as f32) * 100.0
5329    }
5330
5331    fn get_coverage_score(&self, coverage: f32) -> TypeCoverageScore {
5332        match coverage {
5333            score if score >= 90.0 => TypeCoverageScore::Excellent,
5334            score if score >= 70.0 => TypeCoverageScore::Good,
5335            score if score >= 50.0 => TypeCoverageScore::Fair,
5336            score if score >= 30.0 => TypeCoverageScore::Poor,
5337            _ => TypeCoverageScore::Minimal,
5338        }
5339    }
5340
5341    fn get_type_hint_recommendations(
5342        &self,
5343        type_hints: &[TypeHintInfo],
5344        issues: &[TypeSafetyIssue],
5345        coverage: f32,
5346    ) -> Vec<String> {
5347        let mut recommendations = Vec::new();
5348
5349        if coverage < 70.0 {
5350            recommendations.push("Increase type hint coverage for better type safety".to_string());
5351        }
5352
5353        if !issues.is_empty() {
5354            recommendations.push("Address type safety issues identified in the code".to_string());
5355        }
5356
5357        let has_modern_features = type_hints.iter().any(|h| {
5358            h.python_version_required.starts_with("3.8")
5359                || h.python_version_required.starts_with("3.9")
5360                || h.python_version_required.starts_with("3.10")
5361        });
5362
5363        if !has_modern_features {
5364            recommendations.push("Consider using modern Python type features (3.8+)".to_string());
5365        }
5366
5367        let has_complex_types = type_hints.iter().any(|h| {
5368            matches!(
5369                h.complexity,
5370                TypeComplexity::Complex | TypeComplexity::Advanced
5371            )
5372        });
5373
5374        if has_complex_types {
5375            recommendations
5376                .push("Document complex type relationships for maintainability".to_string());
5377        }
5378
5379        if type_hints.iter().any(|h| h.is_generic) {
5380            recommendations
5381                .push("Ensure generic type constraints are properly defined".to_string());
5382        }
5383
5384        recommendations.push("Use type checkers like mypy for static type validation".to_string());
5385        recommendations.push("Consider Protocol types for structural typing".to_string());
5386
5387        recommendations
5388    }
5389
5390    /// Helper methods for security analysis
5391    fn get_security_recommendation(&self, vulnerability_type: &VulnerabilityType) -> String {
5392        match vulnerability_type {
5393            VulnerabilityType::SqlInjection => {
5394                "Use parameterized queries or ORM methods".to_string()
5395            }
5396            VulnerabilityType::CommandInjection => {
5397                "Sanitize user input and avoid shell execution".to_string()
5398            }
5399            VulnerabilityType::DeserializationAttack => {
5400                "Use safe deserialization methods like json.loads".to_string()
5401            }
5402            VulnerabilityType::HardcodedSecrets => {
5403                "Use environment variables or secret management".to_string()
5404            }
5405            _ => "Review security implementation".to_string(),
5406        }
5407    }
5408
5409    fn determine_security_level(
5410        &self,
5411        vulnerabilities: &[SecurityVulnerability],
5412        security_features: &[SecurityFeature],
5413    ) -> SecurityLevel {
5414        let critical_vulns = vulnerabilities
5415            .iter()
5416            .filter(|v| matches!(v.severity, VulnerabilitySeverity::Critical))
5417            .count();
5418        let high_vulns = vulnerabilities
5419            .iter()
5420            .filter(|v| matches!(v.severity, VulnerabilitySeverity::High))
5421            .count();
5422
5423        if critical_vulns > 0 {
5424            SecurityLevel::Vulnerable
5425        } else if high_vulns > 2 {
5426            SecurityLevel::Low
5427        } else if security_features.len() > 2 {
5428            SecurityLevel::High
5429        } else {
5430            SecurityLevel::Medium
5431        }
5432    }
5433
5434    fn get_security_recommendations(
5435        &self,
5436        vulnerabilities: &[SecurityVulnerability],
5437        _security_features: &[SecurityFeature],
5438    ) -> Vec<String> {
5439        let mut recommendations = Vec::new();
5440
5441        if !vulnerabilities.is_empty() {
5442            recommendations.push("Address security vulnerabilities identified in code".to_string());
5443        }
5444
5445        recommendations.push("Implement comprehensive input validation".to_string());
5446        recommendations.push("Use secure authentication and authorization".to_string());
5447        recommendations.push("Enable security headers and CSRF protection".to_string());
5448
5449        recommendations
5450    }
5451
5452    /// Helper methods for performance analysis
5453    fn calculate_performance_score(
5454        &self,
5455        optimizations: &[PerformanceOptimization],
5456        issues: &[PerformanceIssue],
5457    ) -> i32 {
5458        let base_score = 50;
5459        let optimization_bonus = optimizations.len() as i32 * 10;
5460        let issue_penalty = issues
5461            .iter()
5462            .map(|i| match i.severity {
5463                IssueSeverity::Critical => 20,
5464                IssueSeverity::High => 15,
5465                IssueSeverity::Medium => 10,
5466                IssueSeverity::Low => 5,
5467            })
5468            .sum::<i32>();
5469
5470        (base_score + optimization_bonus - issue_penalty).clamp(0, 100)
5471    }
5472
5473    fn get_performance_recommendations(
5474        &self,
5475        _optimizations: &[PerformanceOptimization],
5476        issues: &[PerformanceIssue],
5477    ) -> Vec<String> {
5478        let mut recommendations = Vec::new();
5479
5480        if !issues.is_empty() {
5481            recommendations.push("Address performance issues identified in code".to_string());
5482        }
5483
5484        recommendations.push("Use list comprehensions and generator expressions".to_string());
5485        recommendations.push("Implement caching for expensive operations".to_string());
5486        recommendations.push("Consider async/await for I/O operations".to_string());
5487
5488        recommendations
5489    }
5490
5491    /// Framework-specific analysis methods
5492    fn analyze_django_specifics(&self, content: &str) -> DjangoAnalysis {
5493        DjangoAnalysis {
5494            models_analysis: self.extract_django_models(content),
5495            views_analysis: self.extract_django_views(content),
5496            middleware_usage: self.extract_django_middleware(content),
5497            security_middleware: self.extract_django_security_middleware(content),
5498            signals_usage: self.extract_django_signals(content),
5499            admin_customization: content.contains("admin.site.register")
5500                || content.contains("ModelAdmin"),
5501        }
5502    }
5503
5504    fn analyze_flask_specifics(&self, content: &str) -> FlaskAnalysis {
5505        FlaskAnalysis {
5506            blueprints: self.extract_flask_blueprints(content),
5507            extensions: self.extract_flask_extensions(content),
5508            error_handlers: self.extract_flask_error_handlers(content),
5509            template_usage: content.contains("render_template"),
5510            session_management: content.contains("session["),
5511        }
5512    }
5513
5514    fn analyze_fastapi_specifics(&self, content: &str) -> FastAPIAnalysis {
5515        FastAPIAnalysis {
5516            router_usage: self.extract_fastapi_routers(content),
5517            dependency_injection: self.extract_fastapi_dependencies(content),
5518            background_tasks: content.contains("BackgroundTasks"),
5519            websocket_endpoints: self.extract_fastapi_websockets(content),
5520            middleware: self.extract_fastapi_middleware(content),
5521            response_models: self.extract_fastapi_response_models(content),
5522        }
5523    }
5524
5525    fn analyze_pytest_specifics(&self, content: &str) -> PytestAnalysis {
5526        PytestAnalysis {
5527            fixtures: self.extract_pytest_fixtures(content),
5528            parametrized_tests: self.extract_pytest_parametrized(content),
5529            markers: self.extract_pytest_markers(content),
5530            plugins: self.extract_pytest_plugins(content),
5531            coverage_setup: content.contains("pytest-cov") || content.contains("coverage"),
5532        }
5533    }
5534
5535    // Simplified extraction methods (can be enhanced with more complex parsing)
5536    fn extract_django_models(&self, content: &str) -> Vec<DjangoModelInfo> {
5537        let model_pattern = Regex::new(r"class\s+(\w+)\s*\([^)]*Model[^)]*\)").unwrap();
5538        model_pattern
5539            .captures_iter(content)
5540            .map(|captures| {
5541                let model_name = captures.get(1).unwrap().as_str().to_string();
5542                DjangoModelInfo {
5543                    name: model_name,
5544                    fields: Vec::new(), // Simplified
5545                    relationships: Vec::new(),
5546                    custom_managers: false,
5547                    meta_options: Vec::new(),
5548                }
5549            })
5550            .collect()
5551    }
5552
5553    fn extract_django_views(&self, _content: &str) -> Vec<DjangoViewInfo> {
5554        Vec::new() // Simplified implementation
5555    }
5556
5557    fn extract_django_middleware(&self, _content: &str) -> Vec<String> {
5558        Vec::new() // Simplified implementation
5559    }
5560
5561    fn extract_django_security_middleware(&self, content: &str) -> Vec<String> {
5562        let mut middleware = Vec::new();
5563        if content.contains("SecurityMiddleware") {
5564            middleware.push("SecurityMiddleware".to_string());
5565        }
5566        if content.contains("CsrfViewMiddleware") {
5567            middleware.push("CsrfViewMiddleware".to_string());
5568        }
5569        middleware
5570    }
5571
5572    fn extract_django_signals(&self, content: &str) -> Vec<String> {
5573        let mut signals = Vec::new();
5574        if content.contains("post_save") {
5575            signals.push("post_save".to_string());
5576        }
5577        if content.contains("pre_save") {
5578            signals.push("pre_save".to_string());
5579        }
5580        signals
5581    }
5582
5583    fn extract_flask_blueprints(&self, _content: &str) -> Vec<FlaskBlueprintInfo> {
5584        Vec::new() // Simplified implementation
5585    }
5586
5587    fn extract_flask_extensions(&self, content: &str) -> Vec<String> {
5588        let mut extensions = Vec::new();
5589        if content.contains("Flask-Login") {
5590            extensions.push("Flask-Login".to_string());
5591        }
5592        if content.contains("Flask-SQLAlchemy") {
5593            extensions.push("Flask-SQLAlchemy".to_string());
5594        }
5595        extensions
5596    }
5597
5598    fn extract_flask_error_handlers(&self, _content: &str) -> Vec<String> {
5599        Vec::new() // Simplified implementation
5600    }
5601
5602    fn extract_fastapi_routers(&self, _content: &str) -> Vec<FastAPIRouterInfo> {
5603        Vec::new() // Simplified implementation
5604    }
5605
5606    fn extract_fastapi_dependencies(&self, _content: &str) -> Vec<String> {
5607        Vec::new() // Simplified implementation
5608    }
5609
5610    fn extract_fastapi_websockets(&self, _content: &str) -> Vec<String> {
5611        Vec::new() // Simplified implementation
5612    }
5613
5614    fn extract_fastapi_middleware(&self, _content: &str) -> Vec<String> {
5615        Vec::new() // Simplified implementation
5616    }
5617
5618    fn extract_fastapi_response_models(&self, _content: &str) -> Vec<String> {
5619        Vec::new() // Simplified implementation
5620    }
5621
5622    fn extract_pytest_fixtures(&self, _content: &str) -> Vec<PytestFixtureInfo> {
5623        Vec::new() // Simplified implementation
5624    }
5625
5626    fn extract_pytest_parametrized(&self, _content: &str) -> Vec<String> {
5627        Vec::new() // Simplified implementation
5628    }
5629
5630    fn extract_pytest_markers(&self, _content: &str) -> Vec<String> {
5631        Vec::new() // Simplified implementation
5632    }
5633
5634    fn extract_pytest_plugins(&self, _content: &str) -> Vec<String> {
5635        Vec::new() // Simplified implementation
5636    }
5637
5638    fn get_framework_best_practices(&self, framework: &str) -> Vec<String> {
5639        match framework {
5640            "Django" => vec![
5641                "Use Django ORM instead of raw SQL".to_string(),
5642                "Implement proper authentication and authorization".to_string(),
5643                "Use Django forms for input validation".to_string(),
5644            ],
5645            "Flask" => vec![
5646                "Use blueprints for application modularity".to_string(),
5647                "Implement proper error handling".to_string(),
5648                "Use Flask-WTF for form handling".to_string(),
5649            ],
5650            "FastAPI" => vec![
5651                "Use Pydantic models for request/response validation".to_string(),
5652                "Implement proper dependency injection".to_string(),
5653                "Use async/await for I/O operations".to_string(),
5654            ],
5655            _ => Vec::new(),
5656        }
5657    }
5658
5659    /// Get Python-specific recommendations
5660    pub fn get_python_recommendations(
5661        &self,
5662        decorators: &[DecoratorInfo],
5663        metaclasses: &[MetaclassInfo],
5664        inheritance: &[InheritanceInfo],
5665    ) -> Vec<String> {
5666        let mut recommendations = Vec::new();
5667
5668        // Decorator recommendations
5669        let framework_decorators = decorators.iter().filter(|d| d.framework.is_some()).count();
5670        if framework_decorators > 0 {
5671            recommendations
5672                .push("Consider documenting framework-specific decorator behavior.".to_string());
5673        }
5674
5675        let factory_decorators = decorators.iter().filter(|d| d.is_factory).count();
5676        if factory_decorators > 0 {
5677            recommendations.push(
5678                "Factory decorators detected - ensure proper parameter validation.".to_string(),
5679            );
5680        }
5681
5682        // Metaclass recommendations
5683        if !metaclasses.is_empty() {
5684            recommendations.push(
5685                "Metaclasses detected - document their behavior and impact on subclasses."
5686                    .to_string(),
5687            );
5688            recommendations.push(
5689                "Consider if metaclass functionality could be achieved with simpler patterns."
5690                    .to_string(),
5691            );
5692        }
5693
5694        // Inheritance recommendations
5695        let diamond_inheritance = inheritance
5696            .iter()
5697            .filter(|i| i.has_diamond_inheritance)
5698            .count();
5699        if diamond_inheritance > 0 {
5700            recommendations.push(
5701                "Diamond inheritance detected - verify MRO behavior is as expected.".to_string(),
5702            );
5703        }
5704
5705        let complex_inheritance = inheritance
5706            .iter()
5707            .filter(|i| i.base_classes.len() > 2)
5708            .count();
5709        if complex_inheritance > 0 {
5710            recommendations.push(
5711                "Complex inheritance hierarchies detected - consider composition over inheritance."
5712                    .to_string(),
5713            );
5714        }
5715
5716        recommendations
5717            .push("Use type hints for better code documentation and IDE support.".to_string());
5718        recommendations.push("Consider using dataclasses for simple data containers.".to_string());
5719
5720        recommendations
5721    }
5722}
5723
5724impl Default for PythonAnalyzer {
5725    fn default() -> Self {
5726        Self::new()
5727    }
5728}
5729
5730#[cfg(test)]
5731mod tests {
5732    use super::*;
5733
5734    #[test]
5735    fn test_decorator_analysis() {
5736        let analyzer = PythonAnalyzer::new();
5737
5738        let code = "@app.route('/test')\ndef test_view():\n    pass";
5739        let decorators = analyzer.analyze_decorators(code).unwrap();
5740
5741        assert!(!decorators.is_empty(), "Should detect decorator in code");
5742
5743        // Validate specific decorator detection
5744        let flask_decorator = decorators
5745            .iter()
5746            .find(|d| d.name == "Flask Route")
5747            .expect("Should detect Flask route decorator");
5748
5749        assert!(
5750            !flask_decorator.parameters.is_empty(),
5751            "Flask route should have path parameter"
5752        );
5753        assert!(
5754            flask_decorator.parameters.contains(&"'/test'".to_string()),
5755            "Should capture the route path"
5756        );
5757    }
5758
5759    #[test]
5760    fn test_metaclass_analysis() {
5761        let analyzer = PythonAnalyzer::new();
5762
5763        let code = "class TestClass(BaseClass, metaclass=RegistryMeta):\n    pass";
5764        let metaclasses = analyzer.analyze_metaclasses(code).unwrap();
5765
5766        assert!(!metaclasses.is_empty(), "Should detect metaclass usage");
5767
5768        // Validate specific metaclass detection
5769        let test_metaclass = metaclasses
5770            .iter()
5771            .find(|m| m.name == "TestClass")
5772            .expect("Should detect TestClass with metaclass");
5773
5774        // The metaclass analysis categorizes this as "common" pattern, not the literal type name
5775        assert_eq!(
5776            test_metaclass.metaclass_type, "common",
5777            "Should categorize metaclass pattern correctly"
5778        );
5779        assert!(
5780            !test_metaclass.impact.is_empty(),
5781            "Should analyze metaclass impact"
5782        );
5783    }
5784
5785    #[test]
5786    fn test_inheritance_analysis() {
5787        let analyzer = PythonAnalyzer::new();
5788
5789        let code = "class Child(Parent1, Parent2):\n    pass";
5790        let inheritance = analyzer.analyze_inheritance(code).unwrap();
5791
5792        assert!(!inheritance.is_empty(), "Should not be empty");
5793        assert_eq!(inheritance[0].class_name, "Child");
5794        assert_eq!(inheritance[0].base_classes.len(), 2, "Should have 2 items");
5795    }
5796
5797    #[test]
5798    fn test_decorator_parameter_extraction() {
5799        let analyzer = PythonAnalyzer::new();
5800
5801        let decorator = "@app.route('/test', methods=['GET', 'POST'])";
5802        let params = analyzer.extract_decorator_parameters(decorator);
5803
5804        assert!(!params.is_empty(), "Should not be empty");
5805    }
5806
5807    #[test]
5808    fn test_diamond_inheritance_detection() {
5809        let analyzer = PythonAnalyzer::new();
5810
5811        let base_classes = vec!["Parent1".to_string(), "Parent2".to_string()];
5812        assert!(analyzer.detect_diamond_inheritance(&base_classes));
5813
5814        let single_base = vec!["Parent".to_string()];
5815        assert!(!analyzer.detect_diamond_inheritance(&single_base));
5816    }
5817
5818    #[test]
5819    fn test_mixin_identification() {
5820        let analyzer = PythonAnalyzer::new();
5821
5822        let base_classes = vec![
5823            "BaseMixin".to_string(),
5824            "RegularClass".to_string(),
5825            "UtilMix".to_string(),
5826        ];
5827        let mixins = analyzer.identify_mixins(&base_classes);
5828
5829        assert_eq!(mixins.len(), 2, "Should have 2 items");
5830        assert!(mixins.contains(&"BaseMixin".to_string()));
5831        assert!(mixins.contains(&"UtilMix".to_string()));
5832    }
5833
5834    #[test]
5835    fn test_type_hint_analysis() {
5836        let analyzer = PythonAnalyzer::new();
5837
5838        let code = r#"
5839from typing import List, Dict, Union, Optional, Literal, Final
5840from typing_extensions import Protocol
5841
5842def process_data(items: List[str], mapping: Dict[str, int]) -> Optional[str]:
5843    return None
5844
5845def handle_union(value: Union[str, int]) -> str:
5846    return str(value)
5847
5848class MyProtocol(Protocol):
5849    def method(self) -> None: ...
5850
5851CONSTANT: Final[str] = "value"
5852MODE: Literal["read", "write"] = "read"
5853        "#;
5854
5855        let result = analyzer.analyze_type_hints(code).unwrap();
5856
5857        assert!(
5858            !result.type_hints_detected.is_empty(),
5859            "Should not be empty"
5860        );
5861        assert!(result
5862            .type_hints_detected
5863            .iter()
5864            .any(|h| matches!(h.hint_type, TypeHintType::GenericType(_))));
5865        assert!(result
5866            .type_hints_detected
5867            .iter()
5868            .any(|h| matches!(h.hint_type, TypeHintType::UnionType(_))));
5869        assert!(result
5870            .type_hints_detected
5871            .iter()
5872            .any(|h| matches!(h.hint_type, TypeHintType::OptionalType(_))));
5873        assert!(result.overall_coverage > 0.0);
5874    }
5875
5876    #[test]
5877    fn test_modern_type_features() {
5878        let analyzer = PythonAnalyzer::new();
5879
5880        let code = r#"
5881from typing import Final, Literal
5882from typing_extensions import TypedDict
5883
5884class UserDict(TypedDict):
5885    name: str
5886    age: int
5887
5888CONSTANT: Final[int] = 42
5889STATUS: Literal["active", "inactive"] = "active"
5890
5891# Python 3.10+ union syntax
5892def process(value: str | int) -> str | None:
5893    return None
5894        "#;
5895
5896        let result = analyzer.analyze_type_hints(code).unwrap();
5897
5898        assert!(
5899            !result.modern_type_features.is_empty(),
5900            "Should not be empty"
5901        );
5902        assert!(result
5903            .modern_type_features
5904            .iter()
5905            .any(|f| matches!(f.feature_type, ModernTypeFeatureType::TypedDict)));
5906        assert!(result
5907            .modern_type_features
5908            .iter()
5909            .any(|f| matches!(f.feature_type, ModernTypeFeatureType::FinalType)));
5910        assert!(result
5911            .modern_type_features
5912            .iter()
5913            .any(|f| matches!(f.feature_type, ModernTypeFeatureType::LiteralType)));
5914    }
5915
5916    #[test]
5917    fn test_type_safety_issues() {
5918        let analyzer = PythonAnalyzer::new();
5919
5920        let code = r#"
5921from typing import Any
5922
5923def untyped_function():
5924    return "hello"
5925
5926def another_untyped():
5927    pass
5928
5929def bad_any_usage(x: Any, y: Any, z: Any, a: Any, b: Any, c: Any) -> Any:
5930    return x
5931
5932# type: ignore
5933# type: ignore  
5934# type: ignore
5935# type: ignore
5936        "#;
5937
5938        let result = analyzer.analyze_type_hints(code).unwrap();
5939
5940        assert!(!result.type_safety_issues.is_empty(), "Should not be empty");
5941        assert!(result
5942            .type_safety_issues
5943            .iter()
5944            .any(|issue| matches!(issue.issue_type, TypeSafetyIssueType::AnyTypeOveruse)));
5945        assert!(result
5946            .type_safety_issues
5947            .iter()
5948            .any(|issue| matches!(issue.issue_type, TypeSafetyIssueType::MissingTypeHints)));
5949        assert!(result
5950            .type_safety_issues
5951            .iter()
5952            .any(|issue| matches!(issue.issue_type, TypeSafetyIssueType::TypeIgnoreOveruse)));
5953    }
5954
5955    #[test]
5956    fn test_type_coverage_calculation() {
5957        let analyzer = PythonAnalyzer::new();
5958
5959        // High coverage code
5960        let high_coverage_code = r#"
5961def typed_func1(x: int) -> str:
5962    return str(x)
5963
5964def typed_func2(y: str) -> int:
5965    return len(y)
5966        "#;
5967
5968        let result = analyzer.analyze_type_hints(high_coverage_code).unwrap();
5969        assert!(result.overall_coverage > 50.0);
5970        assert!(matches!(
5971            result.type_coverage_score,
5972            TypeCoverageScore::Good | TypeCoverageScore::Excellent | TypeCoverageScore::Fair
5973        ));
5974
5975        // Low coverage code
5976        let low_coverage_code = r#"
5977def untyped_func1():
5978    return "hello"
5979
5980def untyped_func2():
5981    return 42
5982
5983def typed_func(x: int) -> str:
5984    return str(x)
5985        "#;
5986
5987        let result = analyzer.analyze_type_hints(low_coverage_code).unwrap();
5988        assert!(result.overall_coverage < 100.0);
5989    }
5990
5991    #[test]
5992    fn test_async_await_analysis() {
5993        let analyzer = PythonAnalyzer::new();
5994        let content = r#"
5995import asyncio
5996
5997async def fetch_data():
5998    await asyncio.sleep(1)
5999    return "data"
6000
6001async def process_items():
6002    results = await asyncio.gather(
6003        fetch_data(),
6004        fetch_data(),
6005        fetch_data()
6006    )
6007    return results
6008
6009async def with_context():
6010    async with asyncio.timeout(5):
6011        return await fetch_data()
6012"#;
6013
6014        let result = analyzer.analyze_async_await(content).unwrap();
6015
6016        // Should detect async functions
6017        assert!(
6018            !result.async_functions_detected.is_empty(),
6019            "Should not be empty"
6020        );
6021        assert!(result.async_functions_detected.len() >= 3);
6022
6023        // Should detect concurrency patterns
6024        assert!(
6025            !result.concurrency_patterns.is_empty(),
6026            "Should not be empty"
6027        );
6028
6029        // Should detect modern async features
6030        assert!(
6031            !result.modern_async_features.is_empty(),
6032            "Should not be empty"
6033        );
6034
6035        // Should have a reasonable async score
6036        assert!(result.overall_async_score > 50);
6037    }
6038
6039    #[test]
6040    fn test_async_performance_issues() {
6041        let analyzer = PythonAnalyzer::new();
6042        let content = r#"
6043import asyncio
6044import time
6045
6046async def bad_function():
6047    # Blocking operations in async function
6048    time.sleep(1)
6049    with open("file.txt") as f:
6050        data = f.read()
6051    
6052    # Sequential awaits that could be concurrent
6053    result1 = await fetch_data()
6054    result2 = await fetch_data()
6055    
6056    return result1 + result2
6057
6058async def fetch_data():
6059    await asyncio.sleep(0.1)
6060    return "data"
6061"#;
6062
6063        let result = analyzer.analyze_async_await(content).unwrap();
6064
6065        // Should detect performance issues
6066        assert!(
6067            !result.async_performance_issues.is_empty(),
6068            "Should not be empty"
6069        );
6070
6071        // Should detect blocking operations
6072        let blocking_issues: Vec<_> = result
6073            .async_performance_issues
6074            .iter()
6075            .filter(|issue| {
6076                matches!(
6077                    issue.issue_type,
6078                    AsyncPerformanceIssueType::BlockingIOInAsync
6079                )
6080            })
6081            .collect();
6082        assert!(!blocking_issues.is_empty(), "Should not be empty");
6083
6084        // Should detect missing concurrency
6085        let concurrency_issues: Vec<_> = result
6086            .async_performance_issues
6087            .iter()
6088            .filter(|issue| {
6089                matches!(
6090                    issue.issue_type,
6091                    AsyncPerformanceIssueType::MissingConcurrency
6092                )
6093            })
6094            .collect();
6095        assert!(!concurrency_issues.is_empty(), "Should not be empty");
6096    }
6097
6098    #[test]
6099    fn test_async_security_issues() {
6100        let analyzer = PythonAnalyzer::new();
6101        let content = r#"
6102import asyncio
6103
6104shared_data = {}
6105
6106async def unsafe_function():
6107    # No timeout handling
6108    await some_external_service()
6109    
6110    # Shared state modification without locking
6111    shared_data["key"] = "value"
6112    
6113    # Multiple concurrent operations without proper synchronization
6114    await asyncio.gather(
6115        modify_shared_data(),
6116        modify_shared_data(),
6117        modify_shared_data()
6118    )
6119
6120async def some_external_service():
6121    await asyncio.sleep(1)
6122
6123async def modify_shared_data():
6124    shared_data["counter"] = shared_data.get("counter", 0) + 1
6125"#;
6126
6127        let result = analyzer.analyze_async_await(content).unwrap();
6128
6129        // Should detect security issues
6130        assert!(
6131            !result.async_security_issues.is_empty(),
6132            "Should not be empty"
6133        );
6134
6135        // Should detect timeout vulnerability
6136        let timeout_issues: Vec<_> = result
6137            .async_security_issues
6138            .iter()
6139            .filter(|issue| matches!(issue.issue_type, AsyncSecurityIssueType::AsyncTimeoutVuln))
6140            .collect();
6141        assert!(!timeout_issues.is_empty(), "Should not be empty");
6142    }
6143
6144    #[test]
6145    fn test_modern_async_features() {
6146        let analyzer = PythonAnalyzer::new();
6147        let content = r#"
6148import asyncio
6149import contextvars
6150
6151async def modern_async():
6152    # Modern async features
6153    async with asyncio.timeout(5):
6154        data = await fetch_data()
6155    
6156    # Async comprehension
6157    results = [await process(item) async for item in async_generator()]
6158    
6159    # Context variables
6160    context_var = contextvars.ContextVar('user_id')
6161    
6162    # TaskGroup (Python 3.11+)
6163    async with asyncio.TaskGroup() as tg:
6164        task1 = tg.create_task(fetch_data())
6165        task2 = tg.create_task(fetch_data())
6166    
6167    return results
6168
6169async def async_generator():
6170    for i in range(3):
6171        yield f"item_{i}"
6172
6173async def fetch_data():
6174    return "data"
6175
6176async def process(item):
6177    return f"processed_{item}"
6178
6179if __name__ == "__main__":
6180    asyncio.run(modern_async())
6181"#;
6182
6183        let result = analyzer.analyze_async_await(content).unwrap();
6184
6185        // Should detect modern async features
6186        assert!(
6187            !result.modern_async_features.is_empty(),
6188            "Should not be empty"
6189        );
6190
6191        // Should detect async context managers
6192        let context_manager_features: Vec<_> = result
6193            .modern_async_features
6194            .iter()
6195            .filter(|f| matches!(f.feature_type, ModernAsyncFeatureType::AsyncContextManager))
6196            .collect();
6197        assert!(!context_manager_features.is_empty(), "Should not be empty");
6198
6199        // Should detect TaskGroups
6200        let task_group_features: Vec<_> = result
6201            .modern_async_features
6202            .iter()
6203            .filter(|f| matches!(f.feature_type, ModernAsyncFeatureType::TaskGroups))
6204            .collect();
6205        assert!(!task_group_features.is_empty(), "Should not be empty");
6206
6207        // Should detect asyncio.run
6208        let asyncio_run_features: Vec<_> = result
6209            .modern_async_features
6210            .iter()
6211            .filter(|f| matches!(f.feature_type, ModernAsyncFeatureType::AsyncioRun))
6212            .collect();
6213        assert!(!asyncio_run_features.is_empty(), "Should not be empty");
6214
6215        // Should have recommendations
6216        assert!(!result.recommendations.is_empty(), "Should not be empty");
6217    }
6218
6219    #[test]
6220    fn test_package_dependency_analysis() {
6221        let analyzer = PythonAnalyzer::new();
6222        let content = r#"
6223import requests
6224import pandas as pd
6225from flask import Flask
6226import numpy
6227from django.db import models
6228
6229django>=3.2.0
6230requests==2.28.1
6231pandas>=1.5.0
6232numpy
6233flask==2.0.1
6234"#;
6235
6236        let result = analyzer.analyze_package_dependencies(content).unwrap();
6237
6238        // Should detect dependencies
6239        assert!(!result.dependencies.is_empty(), "Should not be empty");
6240
6241        // Should detect imports
6242        assert!(!result.import_analysis.is_empty(), "Should not be empty");
6243        assert!(result.import_analysis.len() >= 5);
6244
6245        // Should have a reasonable health score
6246        assert!(result.overall_health_score >= 0);
6247        assert!(result.overall_health_score <= 100);
6248
6249        // Should detect issues
6250        assert!(!result.dependency_issues.is_empty(), "Should not be empty");
6251
6252        // Should provide recommendations
6253        assert!(!result.recommendations.is_empty(), "Should not be empty");
6254    }
6255
6256    #[test]
6257    fn test_dependency_issue_detection() {
6258        let analyzer = PythonAnalyzer::new();
6259        let content = r#"
6260import requests
6261import missing_package
6262from some_package import *
6263
6264# Requirements:
6265requests==2.28.1
6266unused_package==1.0.0
6267imp==1.0.0
6268django
6269"#;
6270
6271        let result = analyzer.analyze_package_dependencies(content).unwrap();
6272
6273        // Should detect unused dependency
6274        let unused_issues: Vec<_> = result
6275            .dependency_issues
6276            .iter()
6277            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::UnusedDependency))
6278            .collect();
6279        assert!(!unused_issues.is_empty(), "Should not be empty");
6280
6281        // Should detect missing dependency
6282        let missing_issues: Vec<_> = result
6283            .dependency_issues
6284            .iter()
6285            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::MissingDependency))
6286            .collect();
6287        assert!(!missing_issues.is_empty(), "Should not be empty");
6288
6289        // Should detect unpinned version
6290        let unpinned_issues: Vec<_> = result
6291            .dependency_issues
6292            .iter()
6293            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::UnpinnedVersion))
6294            .collect();
6295        assert!(!unpinned_issues.is_empty(), "Should not be empty");
6296
6297        // Should detect deprecated package
6298        let deprecated_issues: Vec<_> = result
6299            .dependency_issues
6300            .iter()
6301            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::DeprecatedPackage))
6302            .collect();
6303        assert!(!deprecated_issues.is_empty(), "Should not be empty");
6304    }
6305
6306    #[test]
6307    fn test_import_analysis() {
6308        let analyzer = PythonAnalyzer::new();
6309        let content = r#"
6310import os
6311import sys
6312import requests
6313import pandas as pd
6314from flask import Flask, render_template
6315from mymodule import function
6316from .relative import local_function
6317from package import *
6318import numpy as np
6319"#;
6320
6321        let result = analyzer.analyze_package_dependencies(content).unwrap();
6322
6323        // Should categorize imports correctly
6324        let stdlib_imports: Vec<_> = result
6325            .import_analysis
6326            .iter()
6327            .filter(|imp| matches!(imp.module_category, ModuleCategory::StandardLibrary))
6328            .collect();
6329        assert!(stdlib_imports.len() >= 2); // os, sys
6330
6331        let third_party_imports: Vec<_> = result
6332            .import_analysis
6333            .iter()
6334            .filter(|imp| matches!(imp.module_category, ModuleCategory::ThirdParty))
6335            .collect();
6336        assert!(third_party_imports.len() >= 3); // requests, pandas, flask, numpy
6337
6338        // Should detect star import issues
6339        let star_import_issues: Vec<_> = result
6340            .import_analysis
6341            .iter()
6342            .filter(|imp| {
6343                imp.import_issues
6344                    .contains(&ImportIssue::StarImportDangerous)
6345            })
6346            .collect();
6347        assert!(!star_import_issues.is_empty(), "Should not be empty");
6348
6349        // Should detect different import types
6350        let from_imports: Vec<_> = result
6351            .import_analysis
6352            .iter()
6353            .filter(|imp| matches!(imp.import_type, ImportType::FromImport))
6354            .collect();
6355        assert!(!from_imports.is_empty(), "Should not be empty");
6356
6357        let alias_imports: Vec<_> = result
6358            .import_analysis
6359            .iter()
6360            .filter(|imp| matches!(imp.import_type, ImportType::AliasImport))
6361            .collect();
6362        assert!(!alias_imports.is_empty(), "Should not be empty");
6363    }
6364
6365    #[test]
6366    fn test_security_vulnerability_scanning() {
6367        let analyzer = PythonAnalyzer::new();
6368        let content = r#"
6369import urllib3
6370import requests
6371import pyyaml
6372
6373urllib3==1.25.8
6374requests==2.19.1
6375pyyaml==5.3.1
6376"#;
6377
6378        let result = analyzer.analyze_package_dependencies(content).unwrap();
6379
6380        // Should detect security vulnerabilities
6381        assert!(
6382            !result.security_vulnerabilities.is_empty(),
6383            "Should not be empty"
6384        );
6385
6386        // Should have vulnerabilities for known packages
6387        let urllib3_vulns: Vec<_> = result
6388            .security_vulnerabilities
6389            .iter()
6390            .filter(|vuln| vuln.package_name == "urllib3")
6391            .collect();
6392        assert!(!urllib3_vulns.is_empty(), "Should not be empty");
6393
6394        // Should categorize severity correctly
6395        let critical_vulns: Vec<_> = result
6396            .security_vulnerabilities
6397            .iter()
6398            .filter(|vuln| matches!(vuln.severity, SecurityVulnerabilitySeverity::Critical))
6399            .collect();
6400        assert!(!critical_vulns.is_empty(), "Should not be empty");
6401
6402        // Should have CVE information
6403        let vulns_with_cve: Vec<_> = result
6404            .security_vulnerabilities
6405            .iter()
6406            .filter(|vuln| vuln.cve_id.is_some())
6407            .collect();
6408        assert!(!vulns_with_cve.is_empty(), "Should not be empty");
6409    }
6410
6411    #[test]
6412    fn test_virtual_environment_detection() {
6413        let analyzer = PythonAnalyzer::new();
6414        let content = r#"
6415# Virtual environment indicators
6416python -m venv myenv
6417source myenv/bin/activate
6418pip install -r requirements.txt
6419
6420# Conda environment
6421conda create -n myproject python=3.9
6422conda activate myproject
6423
6424# Pipenv
6425pipenv install requests
6426pipenv shell
6427"#;
6428
6429        let result = analyzer.analyze_package_dependencies(content).unwrap();
6430
6431        // Should detect virtual environments
6432        assert!(
6433            !result.virtual_environments.is_empty(),
6434            "Should not be empty"
6435        );
6436
6437        // Should detect different environment types
6438        let venv_envs: Vec<_> = result
6439            .virtual_environments
6440            .iter()
6441            .filter(|env| matches!(env.env_type, VirtualEnvironmentType::Venv))
6442            .collect();
6443        assert!(!venv_envs.is_empty(), "Should not be empty");
6444
6445        let conda_envs: Vec<_> = result
6446            .virtual_environments
6447            .iter()
6448            .filter(|env| matches!(env.env_type, VirtualEnvironmentType::Conda))
6449            .collect();
6450        assert!(!conda_envs.is_empty(), "Should not be empty");
6451
6452        let pipenv_envs: Vec<_> = result
6453            .virtual_environments
6454            .iter()
6455            .filter(|env| matches!(env.env_type, VirtualEnvironmentType::Pipenv))
6456            .collect();
6457        assert!(!pipenv_envs.is_empty(), "Should not be empty");
6458    }
6459
6460    #[test]
6461    fn test_license_analysis() {
6462        let analyzer = PythonAnalyzer::new();
6463        let content = r#"
6464import requests
6465import django
6466import flask
6467
6468requests==2.28.1
6469django==4.1.0
6470flask==2.0.1
6471"#;
6472
6473        let result = analyzer.analyze_package_dependencies(content).unwrap();
6474
6475        // Should analyze licenses
6476        assert!(!result.license_analysis.is_empty(), "Should not be empty");
6477
6478        // Should have license information for dependencies
6479        assert_eq!(result.license_analysis.len(), result.dependencies.len());
6480
6481        // Should assess compatibility
6482        let compatible_licenses: Vec<_> = result
6483            .license_analysis
6484            .iter()
6485            .filter(|license| matches!(license.compatibility, LicenseCompatibility::Compatible))
6486            .collect();
6487        assert!(!compatible_licenses.is_empty(), "Should not be empty");
6488
6489        // Should have license metadata
6490        for license in &result.license_analysis {
6491            assert!(!license.package_name.is_empty(), "Should not be empty");
6492            assert!(matches!(
6493                license.license_type,
6494                LicenseType::MIT
6495                    | LicenseType::Apache2
6496                    | LicenseType::BSD2Clause
6497                    | LicenseType::BSD3Clause
6498                    | LicenseType::Unknown
6499            ));
6500        }
6501    }
6502
6503    #[test]
6504    fn test_modern_features_analysis() {
6505        let analyzer = PythonAnalyzer::new();
6506        let code = r#"
6507            from dataclasses import dataclass
6508            from typing import Optional
6509            import asyncio
6510
6511            @dataclass
6512            class User:
6513                name: str
6514                age: int = 0
6515
6516            async def process_data():
6517                async with asyncio.timeout(10):
6518                    data = [x for x in range(100)]
6519                    processed = (item * 2 for item in data)
6520                    return f"Processed {len(data)} items"
6521
6522            def modern_syntax(value: str | int) -> str:
6523                if (result := calculate(value)) > 10:
6524                    return f"Result: {result:.2f}"
6525                return "Too small"
6526
6527            match value:
6528                case int() if value > 100:
6529                    print("Large number")
6530                case str():
6531                    print("String value")
6532                case _:
6533                    print("Other")
6534        "#;
6535
6536        let analysis = analyzer.analyze_modern_features(code).unwrap();
6537
6538        // Should detect dataclass usage
6539        assert!(
6540            !analysis.dataclass_features.is_empty(),
6541            "Should not be empty"
6542        );
6543
6544        // Should detect f-string usage
6545        assert!(!analysis.fstring_features.is_empty(), "Should not be empty");
6546
6547        // Should detect modern syntax (walrus operator, union types)
6548        assert!(
6549            !analysis.modern_syntax_features.is_empty(),
6550            "Should not be empty"
6551        );
6552
6553        // Should have a reasonable modernity score
6554        assert!(analysis.overall_modernity_score > 50);
6555        assert!(analysis.overall_modernity_score <= 100);
6556
6557        // Should detect appropriate Python version
6558        assert!(analysis
6559            .python_version_detected
6560            .minimum_version
6561            .starts_with("3."));
6562
6563        // Should provide recommendations
6564        assert!(!analysis.recommendations.is_empty(), "Should not be empty");
6565    }
6566
6567    #[test]
6568    fn test_dataclass_feature_detection() {
6569        let analyzer = PythonAnalyzer::new();
6570        let code = r#"
6571            from dataclasses import dataclass, field
6572            from typing import List
6573
6574            @dataclass(frozen=True)
6575            class ImmutableUser:
6576                name: str
6577                tags: List[str] = field(default_factory=list)
6578                
6579                def __post_init__(self):
6580                    object.__setattr__(self, 'processed', True)
6581
6582            class SlottedClass:
6583                __slots__ = ['x', 'y']
6584                
6585                def __init__(self, x, y):
6586                    self.x = x
6587                    self.y = y
6588        "#;
6589
6590        let analysis = analyzer.analyze_modern_features(code).unwrap();
6591
6592        assert!(
6593            !analysis.dataclass_features.is_empty(),
6594            "Should not be empty"
6595        );
6596        let dataclass_info = &analysis.dataclass_features[0];
6597
6598        assert_eq!(
6599            dataclass_info.dataclass_type,
6600            DataclassType::StandardDataclass
6601        );
6602        assert!(dataclass_info
6603            .features_used
6604            .contains(&DataclassFeature::FrozenClass));
6605        assert!(dataclass_info
6606            .features_used
6607            .contains(&DataclassFeature::PostInitProcessing));
6608        assert!(dataclass_info
6609            .features_used
6610            .contains(&DataclassFeature::FieldFactories));
6611        assert!(dataclass_info.best_practices_score > 70);
6612    }
6613
6614    #[test]
6615    fn test_fstring_complexity_analysis() {
6616        let analyzer = PythonAnalyzer::new();
6617        let code = r#"
6618            name = "Alice"
6619            value = 42.5
6620            
6621            # Simple f-string
6622            simple = f"Hello {name}"
6623            
6624            # Complex f-string with formatting
6625            complex = f"Value: {value:.2f}, Length: {len(name)}"
6626            
6627            # Very complex f-string
6628            advanced = f"Result: {calculate_result(value) if value > 0 else 'N/A':.3f}"
6629        "#;
6630
6631        let analysis = analyzer.analyze_modern_features(code).unwrap();
6632
6633        assert!(!analysis.fstring_features.is_empty(), "Should not be empty");
6634        assert!(analysis.fstring_features.len() >= 3);
6635
6636        // Should detect different complexity levels
6637        let complexities: Vec<_> = analysis
6638            .fstring_features
6639            .iter()
6640            .map(|f| &f.complexity)
6641            .collect();
6642
6643        assert!(complexities.contains(&&FStringComplexity::Simple));
6644        assert!(
6645            complexities.contains(&&FStringComplexity::Moderate)
6646                || complexities.contains(&&FStringComplexity::Complex)
6647        );
6648    }
6649
6650    #[test]
6651    fn test_modern_syntax_features() {
6652        let analyzer = PythonAnalyzer::new();
6653        let code = r#"
6654            # Walrus operator (Python 3.8+)
6655            if (length := len(data)) > 10:
6656                print(f"Long data: {length}")
6657
6658            # Union type syntax (Python 3.10+)
6659            def process(value: str | int | None) -> str | None:
6660                return str(value) if value is not None else None
6661
6662            # Positional-only parameters (Python 3.8+)
6663            def func(a, b, /, c, d):
6664                return a + b + c + d
6665
6666            # Modern type hints (Python 3.9+)
6667            data: list[dict[str, int]] = []
6668            mapping: dict[str, set[int]] = {}
6669        "#;
6670
6671        let analysis = analyzer.analyze_modern_features(code).unwrap();
6672
6673        assert!(
6674            !analysis.modern_syntax_features.is_empty(),
6675            "Should not be empty"
6676        );
6677
6678        let syntax_types: Vec<_> = analysis
6679            .modern_syntax_features
6680            .iter()
6681            .map(|s| &s.feature_type)
6682            .collect();
6683
6684        assert!(syntax_types.contains(&&ModernSyntaxType::WalrusOperator));
6685        assert!(syntax_types.contains(&&ModernSyntaxType::TypeUnionOperator));
6686        assert!(syntax_types.contains(&&ModernSyntaxType::PositionalOnlyParams));
6687        assert!(syntax_types.contains(&&ModernSyntaxType::GenericTypeHints));
6688
6689        // Should detect Python 3.10+ as minimum version due to union operator
6690        assert!(analysis.python_version_detected.minimum_version >= "3.10".to_string());
6691    }
6692}