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)] // TODO: 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)] // TODO: 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)] // TODO: 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)] // TODO: 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)] // TODO: 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)] // TODO: 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!("Modern type feature: {}", pattern.name),
2725                                is_best_practice: true,
2726                            });
2727                        }
2728                    }
2729                }
2730            }
2731        }
2732
2733        // Detect type safety issues
2734        self.detect_type_safety_issues(content, &mut type_safety_issues);
2735
2736        // Calculate type coverage
2737        let overall_coverage = self.calculate_type_coverage(content, &type_hints_detected);
2738        let type_coverage_score = self.get_coverage_score(overall_coverage);
2739
2740        // Generate recommendations
2741        let recommendations = self.get_type_hint_recommendations(
2742            &type_hints_detected,
2743            &type_safety_issues,
2744            overall_coverage,
2745        );
2746
2747        Ok(PythonTypeHintAnalysis {
2748            overall_coverage,
2749            type_coverage_score,
2750            type_hints_detected,
2751            type_safety_issues,
2752            modern_type_features,
2753            recommendations,
2754        })
2755    }
2756
2757    /// Analyze Python async/await patterns comprehensively
2758    pub fn analyze_async_await(&self, content: &str) -> Result<PythonAsyncAwaitAnalysis> {
2759        let mut async_functions_detected = Vec::new();
2760        let mut await_usage_patterns = Vec::new();
2761        let mut concurrency_patterns = Vec::new();
2762        let mut async_performance_issues = Vec::new();
2763        let mut async_security_issues = Vec::new();
2764        let mut modern_async_features = Vec::new();
2765
2766        // Analyze async functions
2767        self.analyze_async_functions(content, &mut async_functions_detected);
2768
2769        // Analyze await usage patterns
2770        self.analyze_await_usage(content, &mut await_usage_patterns);
2771
2772        // Analyze concurrency patterns
2773        self.analyze_concurrency_patterns(content, &mut concurrency_patterns);
2774
2775        // Detect async performance issues
2776        self.detect_async_performance_issues(content, &mut async_performance_issues);
2777
2778        // Detect async security issues
2779        self.detect_async_security_issues(content, &mut async_security_issues);
2780
2781        // Detect modern async features
2782        self.detect_modern_async_features(content, &mut modern_async_features);
2783
2784        // Calculate overall async score
2785        let overall_async_score = self.calculate_async_score(
2786            &async_functions_detected,
2787            &concurrency_patterns,
2788            &async_performance_issues,
2789            &async_security_issues,
2790        );
2791
2792        // Generate recommendations
2793        let recommendations = self.get_async_recommendations(
2794            &async_functions_detected,
2795            &await_usage_patterns,
2796            &concurrency_patterns,
2797            &async_performance_issues,
2798            &async_security_issues,
2799        );
2800
2801        Ok(PythonAsyncAwaitAnalysis {
2802            overall_async_score,
2803            async_functions_detected,
2804            await_usage_patterns,
2805            concurrency_patterns,
2806            async_performance_issues,
2807            async_security_issues,
2808            modern_async_features,
2809            recommendations,
2810        })
2811    }
2812
2813    /// Analyze Python package dependencies comprehensively
2814    pub fn analyze_package_dependencies(
2815        &self,
2816        content: &str,
2817    ) -> Result<PythonPackageDependencyAnalysis> {
2818        let mut requirements_files = Vec::new();
2819        let mut dependencies = Vec::new();
2820        let mut dependency_issues = Vec::new();
2821        let mut virtual_environments = Vec::new();
2822        let mut import_analysis = Vec::new();
2823        let mut security_vulnerabilities = Vec::new();
2824        let mut license_analysis = Vec::new();
2825
2826        // Analyze requirements files
2827        self.analyze_requirements_files(content, &mut requirements_files, &mut dependencies);
2828
2829        // Analyze imports
2830        self.analyze_imports(content, &mut import_analysis);
2831
2832        // Detect dependency issues
2833        self.detect_dependency_issues(
2834            content,
2835            &dependencies,
2836            &import_analysis,
2837            &mut dependency_issues,
2838        );
2839
2840        // Detect virtual environments
2841        self.detect_virtual_environments(content, &mut virtual_environments);
2842
2843        // Perform security vulnerability scanning
2844        self.scan_security_vulnerabilities(&dependencies, &mut security_vulnerabilities);
2845
2846        // Analyze licenses
2847        self.analyze_licenses(&dependencies, &mut license_analysis);
2848
2849        // Calculate overall health score
2850        let overall_health_score = self.calculate_dependency_health_score(
2851            &requirements_files,
2852            &dependencies,
2853            &dependency_issues,
2854            &security_vulnerabilities,
2855        );
2856
2857        // Generate recommendations
2858        let recommendations = self.get_dependency_recommendations(
2859            &requirements_files,
2860            &dependencies,
2861            &dependency_issues,
2862            &import_analysis,
2863            &security_vulnerabilities,
2864        );
2865
2866        Ok(PythonPackageDependencyAnalysis {
2867            overall_health_score,
2868            requirements_files,
2869            dependencies,
2870            dependency_issues,
2871            virtual_environments,
2872            import_analysis,
2873            security_vulnerabilities,
2874            license_analysis,
2875            recommendations,
2876        })
2877    }
2878
2879    /// Analyze requirements files
2880    fn analyze_requirements_files(
2881        &self,
2882        content: &str,
2883        requirements_files: &mut Vec<RequirementsFileInfo>,
2884        dependencies: &mut Vec<RequirementInfo>,
2885    ) {
2886        for patterns in self.dependency_patterns.values() {
2887            for pattern in patterns {
2888                if pattern.extraction_method == "line_by_line" {
2889                    // Handle requirements.txt format
2890                    for line in content.lines() {
2891                        if let Some(captures) = pattern.pattern.captures(line) {
2892                            let package_name = captures.get(1).unwrap().as_str();
2893                            let version_spec = captures
2894                                .get(2)
2895                                .and_then(|m| {
2896                                    captures
2897                                        .get(3)
2898                                        .map(|v| format!("{}{}", m.as_str(), v.as_str()))
2899                                })
2900                                .unwrap_or_else(|| "*".to_string());
2901
2902                            dependencies.push(RequirementInfo {
2903                                name: package_name.to_string(),
2904                                version_spec,
2905                                source: RequirementSource::PyPI,
2906                                is_dev_dependency: false,
2907                                is_optional: false,
2908                                extras: Vec::new(),
2909                                markers: Vec::new(),
2910                                metadata: self.get_package_metadata(package_name),
2911                            });
2912                        }
2913                    }
2914
2915                    if !dependencies.is_empty() {
2916                        requirements_files.push(RequirementsFileInfo {
2917                            file_path: "requirements.txt".to_string(),
2918                            file_type: RequirementsFileType::RequirementsTxt,
2919                            dependencies_count: dependencies.len(),
2920                            has_version_pins: dependencies.iter().any(|d| d.version_spec != "*"),
2921                            has_hashes: false,
2922                            uses_constraints: false,
2923                            quality_score: self.assess_requirements_quality(dependencies),
2924                        });
2925                    }
2926                } else if pattern.extraction_method == "toml_array"
2927                    && content.contains("pyproject.toml")
2928                {
2929                    // Handle pyproject.toml format
2930                    if let Some(captures) = pattern.pattern.captures(content) {
2931                        let deps_str = captures.get(1).unwrap().as_str();
2932                        for dep in deps_str.split(',') {
2933                            let clean_dep = dep.trim().trim_matches('"').trim_matches('\'');
2934                            if !clean_dep.is_empty() {
2935                                let parts: Vec<&str> =
2936                                    clean_dep.split(['>', '<', '=', '!', '~']).collect();
2937                                let package_name = parts[0].trim();
2938                                let version_spec = if parts.len() > 1 {
2939                                    clean_dep[package_name.len()..].to_string()
2940                                } else {
2941                                    "*".to_string()
2942                                };
2943
2944                                dependencies.push(RequirementInfo {
2945                                    name: package_name.to_string(),
2946                                    version_spec,
2947                                    source: RequirementSource::PyPI,
2948                                    is_dev_dependency: false,
2949                                    is_optional: false,
2950                                    extras: Vec::new(),
2951                                    markers: Vec::new(),
2952                                    metadata: self.get_package_metadata(package_name),
2953                                });
2954                            }
2955                        }
2956
2957                        requirements_files.push(RequirementsFileInfo {
2958                            file_path: "pyproject.toml".to_string(),
2959                            file_type: RequirementsFileType::PyprojectToml,
2960                            dependencies_count: dependencies.len(),
2961                            has_version_pins: dependencies.iter().any(|d| d.version_spec != "*"),
2962                            has_hashes: false,
2963                            uses_constraints: false,
2964                            quality_score: self.assess_requirements_quality(dependencies),
2965                        });
2966                    }
2967                }
2968            }
2969        }
2970    }
2971
2972    /// Analyze import statements
2973    fn analyze_imports(&self, content: &str, import_analysis: &mut Vec<ImportAnalysisInfo>) {
2974        if let Some(import_patterns) = self.dependency_patterns.get("imports") {
2975            for pattern in import_patterns {
2976                for captures in pattern.pattern.captures_iter(content) {
2977                    let module_name = if pattern.name == "Relative Import" && captures.len() > 2 {
2978                        format!(
2979                            "{}{}",
2980                            captures.get(1).unwrap().as_str(),
2981                            captures.get(2).unwrap().as_str()
2982                        )
2983                    } else {
2984                        captures.get(1).unwrap().as_str().to_string()
2985                    };
2986
2987                    let import_type = self.classify_import_type(&pattern.name);
2988                    let module_category = self.categorize_module(&module_name);
2989                    let usage_count = content.matches(&module_name).count();
2990                    let is_unused = usage_count <= 1; // Only the import itself
2991                    let import_issues =
2992                        self.detect_import_issues(&pattern.name, &module_name, content);
2993
2994                    import_analysis.push(ImportAnalysisInfo {
2995                        import_statement: captures.get(0).unwrap().as_str().to_string(),
2996                        import_type,
2997                        module_category,
2998                        usage_count,
2999                        is_unused,
3000                        import_issues,
3001                        optimization_suggestions: self
3002                            .get_import_optimization_suggestions(&pattern.name, &module_name),
3003                    });
3004                }
3005            }
3006        }
3007    }
3008
3009    /// Detect dependency issues
3010    fn detect_dependency_issues(
3011        &self,
3012        _content: &str,
3013        dependencies: &[RequirementInfo],
3014        import_analysis: &[ImportAnalysisInfo],
3015        issues: &mut Vec<DependencyIssue>,
3016    ) {
3017        // Detect unused dependencies
3018        for dep in dependencies {
3019            let is_imported = import_analysis.iter().any(|imp| {
3020                imp.import_statement.contains(&dep.name)
3021                    || imp.import_statement.contains(&dep.name.replace("-", "_"))
3022            });
3023
3024            if !is_imported {
3025                issues.push(DependencyIssue {
3026                    issue_type: DependencyIssueType::UnusedDependency,
3027                    severity: DependencyIssueSeverity::Low,
3028                    affected_packages: vec![dep.name.clone()],
3029                    description: format!("Dependency '{}' declared but not imported", dep.name),
3030                    recommendation: "Remove unused dependency or add import statement".to_string(),
3031                    auto_fixable: false,
3032                });
3033            }
3034        }
3035
3036        // Detect missing dependencies
3037        for import in import_analysis {
3038            if matches!(import.module_category, ModuleCategory::ThirdParty) {
3039                let module_root = import
3040                    .import_statement
3041                    .split_whitespace()
3042                    .nth(1)
3043                    .unwrap_or("")
3044                    .split('.')
3045                    .next()
3046                    .unwrap_or("");
3047
3048                let is_declared = dependencies.iter().any(|dep| {
3049                    dep.name == module_root || dep.name.replace("-", "_") == module_root
3050                });
3051
3052                if !is_declared && !module_root.is_empty() {
3053                    issues.push(DependencyIssue {
3054                        issue_type: DependencyIssueType::MissingDependency,
3055                        severity: DependencyIssueSeverity::High,
3056                        affected_packages: vec![module_root.to_string()],
3057                        description: format!(
3058                            "Module '{}' imported but not declared as dependency",
3059                            module_root
3060                        ),
3061                        recommendation: "Add missing dependency to requirements".to_string(),
3062                        auto_fixable: true,
3063                    });
3064                }
3065            }
3066        }
3067
3068        // Detect unpinned versions
3069        for dep in dependencies {
3070            if dep.version_spec == "*" || dep.version_spec.is_empty() {
3071                issues.push(DependencyIssue {
3072                    issue_type: DependencyIssueType::UnpinnedVersion,
3073                    severity: DependencyIssueSeverity::Medium,
3074                    affected_packages: vec![dep.name.clone()],
3075                    description: format!("Dependency '{}' has no version constraint", dep.name),
3076                    recommendation: "Pin dependency versions for reproducible builds".to_string(),
3077                    auto_fixable: false,
3078                });
3079            }
3080        }
3081
3082        // Detect deprecated packages
3083        let deprecated_packages = ["imp", "optparse", "platform", "distutils"];
3084        for dep in dependencies {
3085            if deprecated_packages.contains(&dep.name.as_str()) {
3086                issues.push(DependencyIssue {
3087                    issue_type: DependencyIssueType::DeprecatedPackage,
3088                    severity: DependencyIssueSeverity::Medium,
3089                    affected_packages: vec![dep.name.clone()],
3090                    description: format!("Package '{}' is deprecated", dep.name),
3091                    recommendation: "Consider migrating to modern alternatives".to_string(),
3092                    auto_fixable: false,
3093                });
3094            }
3095        }
3096    }
3097
3098    /// Detect virtual environments
3099    fn detect_virtual_environments(
3100        &self,
3101        content: &str,
3102        virtual_environments: &mut Vec<VirtualEnvironmentInfo>,
3103    ) {
3104        // Check for virtual environment indicators
3105        if content.contains("venv") || content.contains("virtualenv") {
3106            virtual_environments.push(VirtualEnvironmentInfo {
3107                env_type: VirtualEnvironmentType::Venv,
3108                location: "./venv".to_string(),
3109                python_version: "3.x".to_string(),
3110                is_active: true,
3111                packages_count: 0,
3112                env_variables: Vec::new(),
3113                configuration: VirtualEnvironmentConfig {
3114                    isolated: true,
3115                    system_site_packages: false,
3116                    pip_version: None,
3117                    setuptools_version: None,
3118                    custom_configurations: Vec::new(),
3119                },
3120            });
3121        }
3122
3123        if content.contains("conda") || content.contains("environment.yml") {
3124            virtual_environments.push(VirtualEnvironmentInfo {
3125                env_type: VirtualEnvironmentType::Conda,
3126                location: "conda environment".to_string(),
3127                python_version: "3.x".to_string(),
3128                is_active: true,
3129                packages_count: 0,
3130                env_variables: Vec::new(),
3131                configuration: VirtualEnvironmentConfig {
3132                    isolated: true,
3133                    system_site_packages: false,
3134                    pip_version: None,
3135                    setuptools_version: None,
3136                    custom_configurations: Vec::new(),
3137                },
3138            });
3139        }
3140
3141        if content.contains("pipenv") || content.contains("Pipfile") {
3142            virtual_environments.push(VirtualEnvironmentInfo {
3143                env_type: VirtualEnvironmentType::Pipenv,
3144                location: "pipenv environment".to_string(),
3145                python_version: "3.x".to_string(),
3146                is_active: true,
3147                packages_count: 0,
3148                env_variables: Vec::new(),
3149                configuration: VirtualEnvironmentConfig {
3150                    isolated: true,
3151                    system_site_packages: false,
3152                    pip_version: None,
3153                    setuptools_version: None,
3154                    custom_configurations: Vec::new(),
3155                },
3156            });
3157        }
3158    }
3159
3160    /// Scan for security vulnerabilities
3161    fn scan_security_vulnerabilities(
3162        &self,
3163        dependencies: &[RequirementInfo],
3164        vulnerabilities: &mut Vec<SecurityVulnerabilityInfo>,
3165    ) {
3166        // Simplified vulnerability database - in production, this would query real databases
3167        let known_vulnerabilities = vec![
3168            ("urllib3", "1.25.8", "CVE-2020-26137", "Critical"),
3169            ("requests", "2.19.1", "CVE-2018-18074", "High"),
3170            ("pyyaml", "5.3.1", "CVE-2020-14343", "High"),
3171            ("django", "2.2.12", "CVE-2020-13254", "Medium"),
3172            ("flask", "1.1.1", "CVE-2019-1010083", "Medium"),
3173        ];
3174
3175        for dep in dependencies {
3176            for (vuln_package, vuln_version, cve_id, severity) in &known_vulnerabilities {
3177                if dep.name == *vuln_package {
3178                    let severity_enum = match *severity {
3179                        "Critical" => SecurityVulnerabilitySeverity::Critical,
3180                        "High" => SecurityVulnerabilitySeverity::High,
3181                        "Medium" => SecurityVulnerabilitySeverity::Medium,
3182                        _ => SecurityVulnerabilitySeverity::Low,
3183                    };
3184
3185                    vulnerabilities.push(SecurityVulnerabilityInfo {
3186                        cve_id: Some(cve_id.to_string()),
3187                        advisory_id: None,
3188                        package_name: dep.name.clone(),
3189                        affected_versions: vec![vuln_version.to_string()],
3190                        fixed_version: Some("Latest".to_string()),
3191                        severity: severity_enum,
3192                        vulnerability_type: VulnerabilityCategory::CodeExecution,
3193                        description: format!(
3194                            "Security vulnerability in {} {}",
3195                            vuln_package, vuln_version
3196                        ),
3197                        references: vec![format!(
3198                            "https://cve.mitre.org/cgi-bin/cvename.cgi?name={}",
3199                            cve_id
3200                        )],
3201                        published_date: Some("2020-01-01".to_string()),
3202                        last_modified: Some("2020-01-01".to_string()),
3203                    });
3204                }
3205            }
3206        }
3207    }
3208
3209    /// Analyze package licenses
3210    fn analyze_licenses(
3211        &self,
3212        dependencies: &[RequirementInfo],
3213        license_analysis: &mut Vec<LicenseInfo>,
3214    ) {
3215        for dep in dependencies {
3216            // Use metadata from package
3217            let license_type = self.parse_license_type(&dep.metadata.license);
3218            let compatibility = self.assess_license_compatibility(&license_type);
3219
3220            license_analysis.push(LicenseInfo {
3221                package_name: dep.name.clone(),
3222                license_type: license_type.clone(),
3223                license_text: None,
3224                compatibility,
3225                commercial_use_allowed: self.is_commercial_use_allowed(&license_type),
3226                distribution_allowed: self.is_distribution_allowed(&license_type),
3227                modification_allowed: self.is_modification_allowed(&license_type),
3228                patent_grant: self.has_patent_grant(&license_type),
3229                copyleft: self.is_copyleft(&license_type),
3230            });
3231        }
3232    }
3233
3234    /// Helper methods for dependency analysis
3235    fn get_package_metadata(&self, package_name: &str) -> PackageMetadata {
3236        // Simplified metadata - in production, this would query PyPI API
3237        PackageMetadata {
3238            description: format!("Package: {}", package_name),
3239            author: "Unknown".to_string(),
3240            license: "MIT".to_string(),
3241            homepage: None,
3242            documentation: None,
3243            last_updated: None,
3244            download_count: None,
3245            maintenance_status: MaintenanceStatus::Unknown,
3246        }
3247    }
3248
3249    fn assess_requirements_quality(
3250        &self,
3251        dependencies: &[RequirementInfo],
3252    ) -> DependencyQualityScore {
3253        let pinned_count = dependencies
3254            .iter()
3255            .filter(|d| d.version_spec != "*")
3256            .count();
3257        let pinned_ratio = if dependencies.is_empty() {
3258            0.0
3259        } else {
3260            pinned_count as f32 / dependencies.len() as f32
3261        };
3262
3263        match pinned_ratio {
3264            r if r >= 0.9 => DependencyQualityScore::Excellent,
3265            r if r >= 0.7 => DependencyQualityScore::Good,
3266            r if r >= 0.5 => DependencyQualityScore::Fair,
3267            r if r >= 0.3 => DependencyQualityScore::Poor,
3268            _ => DependencyQualityScore::Critical,
3269        }
3270    }
3271
3272    fn classify_import_type(&self, pattern_name: &str) -> ImportType {
3273        match pattern_name {
3274            "Standard Import" => ImportType::StandardImport,
3275            "From Import" => ImportType::FromImport,
3276            "Star Import" => ImportType::StarImport,
3277            "Alias Import" => ImportType::AliasImport,
3278            "Relative Import" => ImportType::RelativeImport,
3279            _ => ImportType::StandardImport,
3280        }
3281    }
3282
3283    fn categorize_module(&self, module_name: &str) -> ModuleCategory {
3284        // Standard library modules
3285        let stdlib_modules = vec![
3286            "os",
3287            "sys",
3288            "re",
3289            "json",
3290            "urllib",
3291            "http",
3292            "datetime",
3293            "collections",
3294            "itertools",
3295            "functools",
3296            "pathlib",
3297            "typing",
3298            "asyncio",
3299            "threading",
3300            "multiprocessing",
3301            "subprocess",
3302            "logging",
3303            "unittest",
3304            "sqlite3",
3305        ];
3306
3307        let root_module = module_name.split('.').next().unwrap_or(module_name);
3308
3309        if stdlib_modules.contains(&root_module) {
3310            ModuleCategory::StandardLibrary
3311        } else if root_module.starts_with('.') {
3312            ModuleCategory::Local
3313        } else {
3314            ModuleCategory::ThirdParty
3315        }
3316    }
3317
3318    fn detect_import_issues(
3319        &self,
3320        pattern_name: &str,
3321        module_name: &str,
3322        content: &str,
3323    ) -> Vec<ImportIssue> {
3324        let mut issues = Vec::new();
3325
3326        if pattern_name == "Star Import" {
3327            issues.push(ImportIssue::StarImportDangerous);
3328        }
3329
3330        // Check for circular imports (simplified)
3331        if content.contains(&format!("from {} import", module_name))
3332            && content.contains(&format!("import {}", module_name))
3333        {
3334            issues.push(ImportIssue::CircularImport);
3335        }
3336
3337        // Check for deprecated modules
3338        let deprecated_modules = ["imp", "optparse", "platform.dist"];
3339        if deprecated_modules
3340            .iter()
3341            .any(|&dep| module_name.contains(dep))
3342        {
3343            issues.push(ImportIssue::DeprecatedImport);
3344        }
3345
3346        issues
3347    }
3348
3349    fn get_import_optimization_suggestions(
3350        &self,
3351        pattern_name: &str,
3352        module_name: &str,
3353    ) -> Vec<String> {
3354        let mut suggestions = Vec::new();
3355
3356        if pattern_name == "Star Import" {
3357            suggestions.push("Replace star import with specific imports".to_string());
3358        }
3359
3360        if module_name == "pandas" || module_name == "numpy" {
3361            suggestions.push("Consider lazy loading for large libraries".to_string());
3362        }
3363
3364        suggestions
3365    }
3366
3367    fn parse_license_type(&self, license_str: &str) -> LicenseType {
3368        match license_str.to_lowercase().as_str() {
3369            "mit" => LicenseType::MIT,
3370            "apache-2.0" | "apache 2.0" => LicenseType::Apache2,
3371            "gpl-2.0" | "gpl v2" => LicenseType::GPL2,
3372            "gpl-3.0" | "gpl v3" => LicenseType::GPL3,
3373            "bsd-2-clause" => LicenseType::BSD2Clause,
3374            "bsd-3-clause" => LicenseType::BSD3Clause,
3375            "lgpl" => LicenseType::LGPL,
3376            "mozilla" | "mpl-2.0" => LicenseType::Mozilla,
3377            "unlicense" => LicenseType::Unlicense,
3378            _ => LicenseType::Unknown,
3379        }
3380    }
3381
3382    fn assess_license_compatibility(&self, license_type: &LicenseType) -> LicenseCompatibility {
3383        match license_type {
3384            LicenseType::MIT
3385            | LicenseType::Apache2
3386            | LicenseType::BSD2Clause
3387            | LicenseType::BSD3Clause => LicenseCompatibility::Compatible,
3388            LicenseType::GPL2 | LicenseType::GPL3 => LicenseCompatibility::RequiresReview,
3389            LicenseType::LGPL => LicenseCompatibility::ConditionallyCompatible,
3390            _ => LicenseCompatibility::Unknown,
3391        }
3392    }
3393
3394    fn is_commercial_use_allowed(&self, license_type: &LicenseType) -> bool {
3395        !matches!(license_type, LicenseType::GPL2 | LicenseType::GPL3)
3396    }
3397
3398    fn is_distribution_allowed(&self, license_type: &LicenseType) -> bool {
3399        !matches!(license_type, LicenseType::Proprietary)
3400    }
3401
3402    fn is_modification_allowed(&self, license_type: &LicenseType) -> bool {
3403        !matches!(license_type, LicenseType::Proprietary)
3404    }
3405
3406    fn has_patent_grant(&self, license_type: &LicenseType) -> bool {
3407        matches!(license_type, LicenseType::Apache2 | LicenseType::Mozilla)
3408    }
3409
3410    fn is_copyleft(&self, license_type: &LicenseType) -> bool {
3411        matches!(
3412            license_type,
3413            LicenseType::GPL2 | LicenseType::GPL3 | LicenseType::LGPL
3414        )
3415    }
3416
3417    fn calculate_dependency_health_score(
3418        &self,
3419        requirements_files: &[RequirementsFileInfo],
3420        dependencies: &[RequirementInfo],
3421        issues: &[DependencyIssue],
3422        vulnerabilities: &[SecurityVulnerabilityInfo],
3423    ) -> i32 {
3424        let mut score = 100;
3425
3426        // Deduct points for issues
3427        for issue in issues {
3428            let deduction = match issue.severity {
3429                DependencyIssueSeverity::Critical => 20,
3430                DependencyIssueSeverity::High => 15,
3431                DependencyIssueSeverity::Medium => 10,
3432                DependencyIssueSeverity::Low => 5,
3433                DependencyIssueSeverity::Info => 2,
3434            };
3435            score -= deduction;
3436        }
3437
3438        // Deduct points for vulnerabilities
3439        for vuln in vulnerabilities {
3440            let deduction = match vuln.severity {
3441                SecurityVulnerabilitySeverity::Critical => 25,
3442                SecurityVulnerabilitySeverity::High => 20,
3443                SecurityVulnerabilitySeverity::Medium => 15,
3444                SecurityVulnerabilitySeverity::Low => 10,
3445                _ => 5,
3446            };
3447            score -= deduction;
3448        }
3449
3450        // Add points for good practices
3451        if !requirements_files.is_empty() {
3452            score += 10;
3453        }
3454
3455        let pinned_deps = dependencies
3456            .iter()
3457            .filter(|d| d.version_spec != "*")
3458            .count();
3459        let pinned_ratio = if dependencies.is_empty() {
3460            0.0
3461        } else {
3462            pinned_deps as f32 / dependencies.len() as f32
3463        };
3464
3465        score += (pinned_ratio * 20.0) as i32;
3466
3467        score.clamp(0, 100)
3468    }
3469
3470    fn get_dependency_recommendations(
3471        &self,
3472        requirements_files: &[RequirementsFileInfo],
3473        dependencies: &[RequirementInfo],
3474        issues: &[DependencyIssue],
3475        import_analysis: &[ImportAnalysisInfo],
3476        vulnerabilities: &[SecurityVulnerabilityInfo],
3477    ) -> Vec<String> {
3478        let mut recommendations = Vec::new();
3479
3480        if requirements_files.is_empty() {
3481            recommendations
3482                .push("Create a requirements.txt file to track dependencies".to_string());
3483        }
3484
3485        let unpinned_count = dependencies
3486            .iter()
3487            .filter(|d| d.version_spec == "*")
3488            .count();
3489        if unpinned_count > 0 {
3490            recommendations.push(format!(
3491                "Pin {} unpinned dependencies for reproducible builds",
3492                unpinned_count
3493            ));
3494        }
3495
3496        if !vulnerabilities.is_empty() {
3497            recommendations.push(format!(
3498                "Update {} packages with known security vulnerabilities",
3499                vulnerabilities.len()
3500            ));
3501        }
3502
3503        let unused_imports = import_analysis.iter().filter(|i| i.is_unused).count();
3504        if unused_imports > 0 {
3505            recommendations.push(format!(
3506                "Remove {} unused import statements",
3507                unused_imports
3508            ));
3509        }
3510
3511        let star_imports = import_analysis
3512            .iter()
3513            .filter(|i| matches!(i.import_type, ImportType::StarImport))
3514            .count();
3515        if star_imports > 0 {
3516            recommendations.push(format!(
3517                "Replace {} star imports with specific imports",
3518                star_imports
3519            ));
3520        }
3521
3522        let critical_issues = issues
3523            .iter()
3524            .filter(|i| matches!(i.severity, DependencyIssueSeverity::Critical))
3525            .count();
3526        if critical_issues > 0 {
3527            recommendations.push("Address critical dependency issues immediately".to_string());
3528        }
3529
3530        recommendations
3531            .push("Consider using dependency scanning tools like Safety or Bandit".to_string());
3532        recommendations.push("Set up automated dependency updates with Dependabot".to_string());
3533
3534        recommendations
3535    }
3536
3537    /// Analyze modern Python features comprehensively
3538    pub fn analyze_modern_features(&self, content: &str) -> Result<ModernPythonFeatureAnalysis> {
3539        let mut dataclass_features = Vec::new();
3540        let mut context_manager_features = Vec::new();
3541        let mut fstring_features = Vec::new();
3542        let mut pattern_matching_features = Vec::new();
3543        let mut generator_features = Vec::new();
3544        let mut decorator_features = Vec::new();
3545        let mut modern_syntax_features = Vec::new();
3546
3547        // Analyze dataclasses
3548        self.analyze_dataclasses(content, &mut dataclass_features);
3549
3550        // Analyze context managers
3551        self.analyze_context_managers(content, &mut context_manager_features);
3552
3553        // Analyze f-strings
3554        self.analyze_fstrings(content, &mut fstring_features);
3555
3556        // Analyze pattern matching
3557        self.analyze_pattern_matching(content, &mut pattern_matching_features);
3558
3559        // Analyze generators
3560        self.analyze_generators(content, &mut generator_features);
3561
3562        // Analyze modern decorators
3563        self.analyze_modern_decorators(content, &mut decorator_features);
3564
3565        // Analyze modern syntax
3566        self.analyze_modern_syntax(content, &mut modern_syntax_features);
3567
3568        // Detect Python version and compatibility
3569        let python_version_detected = self.detect_python_version(content);
3570
3571        // Calculate overall modernity score
3572        let overall_modernity_score = self.calculate_modernity_score(
3573            &dataclass_features,
3574            &context_manager_features,
3575            &fstring_features,
3576            &pattern_matching_features,
3577            &generator_features,
3578            &decorator_features,
3579            &modern_syntax_features,
3580        );
3581
3582        // Generate recommendations
3583        let recommendations = self.get_modern_feature_recommendations(
3584            &dataclass_features,
3585            &context_manager_features,
3586            &fstring_features,
3587            &pattern_matching_features,
3588            &generator_features,
3589            &decorator_features,
3590            &modern_syntax_features,
3591            &python_version_detected,
3592        );
3593
3594        Ok(ModernPythonFeatureAnalysis {
3595            overall_modernity_score,
3596            python_version_detected,
3597            dataclass_features,
3598            context_manager_features,
3599            fstring_features,
3600            pattern_matching_features,
3601            generator_features,
3602            decorator_features,
3603            modern_syntax_features,
3604            recommendations,
3605        })
3606    }
3607
3608    /// Analyze dataclass usage patterns
3609    fn analyze_dataclasses(&self, content: &str, dataclass_features: &mut Vec<DataclassInfo>) {
3610        if let Some(patterns) = self.modern_feature_patterns.get("dataclass") {
3611            for pattern in patterns {
3612                for captures in pattern.pattern.captures_iter(content) {
3613                    let full_match = captures.get(0).unwrap().as_str();
3614
3615                    let dataclass_type = match pattern.name.as_str() {
3616                        "Dataclass Decorator" => DataclassType::StandardDataclass,
3617                        "Pydantic Model" => DataclassType::PydanticModel,
3618                        "Named Tuple" => DataclassType::NamedTuple,
3619                        _ => DataclassType::StandardDataclass,
3620                    };
3621
3622                    let class_name = self.extract_dataclass_name(full_match, content);
3623                    let fields = self.analyze_dataclass_fields(content, &class_name);
3624                    let features_used = self.detect_dataclass_features(content, &class_name);
3625                    let complexity = self.assess_dataclass_complexity(&fields, &features_used);
3626                    let best_practices_score =
3627                        self.score_dataclass_best_practices(&fields, &features_used);
3628                    let recommendations =
3629                        self.get_dataclass_recommendations(&features_used, best_practices_score);
3630
3631                    dataclass_features.push(DataclassInfo {
3632                        class_name,
3633                        dataclass_type,
3634                        fields,
3635                        features_used,
3636                        complexity,
3637                        best_practices_score,
3638                        recommendations,
3639                    });
3640                }
3641            }
3642        }
3643    }
3644
3645    /// Analyze context manager usage
3646    fn analyze_context_managers(
3647        &self,
3648        content: &str,
3649        context_features: &mut Vec<ContextManagerInfo>,
3650    ) {
3651        if let Some(patterns) = self.modern_feature_patterns.get("context_manager") {
3652            for pattern in patterns {
3653                for captures in pattern.pattern.captures_iter(content) {
3654                    let full_match = captures.get(0).unwrap().as_str();
3655
3656                    let context_type = match pattern.name.as_str() {
3657                        "With Statement" => ContextManagerType::BuiltInFileManager,
3658                        "Async With" => ContextManagerType::AsyncContextManager,
3659                        "Context Manager Protocol" => ContextManagerType::CustomContextManager,
3660                        "Contextlib Manager" => ContextManagerType::ContextlibManager,
3661                        _ => ContextManagerType::BuiltInFileManager,
3662                    };
3663
3664                    let usage_pattern = self.analyze_context_usage_pattern(content, full_match);
3665                    let resource_management =
3666                        self.assess_resource_management_quality(content, full_match);
3667                    let error_handling = self.assess_context_error_handling(content, full_match);
3668                    let is_async = pattern.name.contains("Async");
3669                    let nested_level = self.calculate_context_nesting_level(content, full_match);
3670                    let best_practices_followed =
3671                        self.check_context_best_practices(content, full_match);
3672
3673                    context_features.push(ContextManagerInfo {
3674                        context_type,
3675                        usage_pattern,
3676                        resource_management,
3677                        error_handling,
3678                        is_async,
3679                        nested_level,
3680                        best_practices_followed,
3681                    });
3682                }
3683            }
3684        }
3685    }
3686
3687    /// Analyze f-string usage
3688    fn analyze_fstrings(&self, content: &str, fstring_features: &mut Vec<FStringInfo>) {
3689        if let Some(patterns) = self.modern_feature_patterns.get("fstring") {
3690            for pattern in patterns {
3691                for captures in pattern.pattern.captures_iter(content) {
3692                    let expression = captures.get(0).unwrap().as_str().to_string();
3693
3694                    let complexity = self.assess_fstring_complexity(&expression);
3695                    let features_used = self.detect_fstring_features(&expression);
3696                    let performance_impact =
3697                        self.assess_fstring_performance(&expression, &features_used);
3698                    let formatting_quality = self.assess_formatting_quality(&expression);
3699                    let readability_score = self.calculate_fstring_readability(&expression);
3700
3701                    fstring_features.push(FStringInfo {
3702                        expression,
3703                        complexity,
3704                        features_used,
3705                        performance_impact,
3706                        formatting_quality,
3707                        readability_score,
3708                    });
3709                }
3710            }
3711        }
3712    }
3713
3714    /// Analyze pattern matching (Python 3.10+)
3715    fn analyze_pattern_matching(
3716        &self,
3717        content: &str,
3718        pattern_features: &mut Vec<PatternMatchingInfo>,
3719    ) {
3720        if let Some(_patterns) = self.modern_feature_patterns.get("pattern_matching") {
3721            // Look for complete match statements
3722            let match_regex = Regex::new(r"(?m)^(\s*)match\s+[^:]+:(.*?)$").unwrap();
3723            for captures in match_regex.captures_iter(content) {
3724                let match_statement = captures.get(0).unwrap().as_str().to_string();
3725
3726                let pattern_types = self.analyze_match_patterns(&match_statement);
3727                let complexity = self.assess_pattern_complexity(&pattern_types);
3728                let has_guards = match_statement.contains("if ");
3729                let is_exhaustive = self.check_pattern_exhaustiveness(&match_statement);
3730                let performance_characteristics =
3731                    self.assess_match_performance(&pattern_types, &match_statement);
3732                let best_practices_score =
3733                    self.score_pattern_best_practices(&pattern_types, has_guards, is_exhaustive);
3734
3735                pattern_features.push(PatternMatchingInfo {
3736                    match_statement,
3737                    pattern_types,
3738                    complexity,
3739                    has_guards,
3740                    is_exhaustive,
3741                    performance_characteristics,
3742                    best_practices_score,
3743                });
3744            }
3745        }
3746    }
3747
3748    /// Analyze generator patterns
3749    fn analyze_generators(&self, content: &str, generator_features: &mut Vec<GeneratorInfo>) {
3750        if let Some(patterns) = self.modern_feature_patterns.get("generator") {
3751            for pattern in patterns {
3752                for captures in pattern.pattern.captures_iter(content) {
3753                    let full_match = captures.get(0).unwrap().as_str();
3754
3755                    let generator_type = match pattern.name.as_str() {
3756                        "Generator Function" => GeneratorType::GeneratorFunction,
3757                        "Generator Expression" => GeneratorType::GeneratorExpression,
3758                        "Async Generator" => GeneratorType::AsyncGenerator,
3759                        _ => GeneratorType::GeneratorFunction,
3760                    };
3761
3762                    let usage_pattern = self.classify_generator_usage_pattern(content, full_match);
3763                    let memory_efficiency =
3764                        self.assess_generator_memory_efficiency(content, full_match);
3765                    let complexity = self.assess_generator_complexity(content, full_match);
3766                    let is_async = pattern.name.contains("Async");
3767                    let yield_analysis = self.analyze_yield_usage(content, full_match);
3768                    let optimization_opportunities =
3769                        self.identify_generator_optimizations(content, full_match);
3770
3771                    generator_features.push(GeneratorInfo {
3772                        generator_type,
3773                        usage_pattern,
3774                        memory_efficiency,
3775                        complexity,
3776                        is_async,
3777                        yield_analysis,
3778                        optimization_opportunities,
3779                    });
3780                }
3781            }
3782        }
3783    }
3784
3785    /// Analyze modern decorator usage
3786    fn analyze_modern_decorators(
3787        &self,
3788        content: &str,
3789        decorator_features: &mut Vec<ModernDecoratorInfo>,
3790    ) {
3791        let decorator_regex = Regex::new(r"@(\w+)(?:\([^)]*\))?").unwrap();
3792        for captures in decorator_regex.captures_iter(content) {
3793            let decorator_name = captures.get(1).unwrap().as_str().to_string();
3794            let full_decorator = captures.get(0).unwrap().as_str();
3795
3796            let decorator_category = self.classify_decorator_category(&decorator_name);
3797            let usage_pattern = self.analyze_decorator_usage_pattern(content, full_decorator);
3798            let complexity = self.assess_decorator_complexity(full_decorator);
3799            let is_factory = full_decorator.contains('(');
3800            let is_async = content.contains("async def") && content.contains(&decorator_name);
3801            let parameters = self.extract_decorator_parameters(full_decorator);
3802            let best_practices_score =
3803                self.score_decorator_best_practices(&decorator_category, &usage_pattern);
3804
3805            decorator_features.push(ModernDecoratorInfo {
3806                decorator_name,
3807                decorator_category,
3808                usage_pattern,
3809                complexity,
3810                is_factory,
3811                is_async,
3812                parameters,
3813                best_practices_score,
3814            });
3815        }
3816    }
3817
3818    /// Analyze modern syntax features
3819    fn analyze_modern_syntax(&self, content: &str, syntax_features: &mut Vec<ModernSyntaxInfo>) {
3820        if let Some(patterns) = self.modern_feature_patterns.get("modern_syntax") {
3821            for pattern in patterns {
3822                let usage_count = pattern.pattern.find_iter(content).count();
3823                if usage_count > 0 {
3824                    let feature_type = match pattern.name.as_str() {
3825                        "Walrus Operator" => ModernSyntaxType::WalrusOperator,
3826                        "Positional Only Parameters" => ModernSyntaxType::PositionalOnlyParams,
3827                        "Union Type Operator" => ModernSyntaxType::TypeUnionOperator,
3828                        "Dictionary Union" => ModernSyntaxType::DictUnionOperator,
3829                        "Generic Type Hints" => ModernSyntaxType::GenericTypeHints,
3830                        _ => ModernSyntaxType::WalrusOperator,
3831                    };
3832
3833                    let complexity = self.assess_syntax_complexity(content, &pattern.pattern);
3834                    let best_practices_followed =
3835                        self.check_syntax_best_practices(content, &feature_type);
3836                    let migration_suggestions =
3837                        self.get_syntax_migration_suggestions(&feature_type, usage_count);
3838
3839                    syntax_features.push(ModernSyntaxInfo {
3840                        feature_type,
3841                        python_version: pattern.python_version.clone(),
3842                        usage_count,
3843                        complexity,
3844                        best_practices_followed,
3845                        migration_suggestions,
3846                    });
3847                }
3848            }
3849        }
3850    }
3851
3852    /// Detect minimum Python version required
3853    fn detect_python_version(&self, content: &str) -> PythonVersionDetected {
3854        let mut features_by_version = Vec::new();
3855        let mut compatibility_issues = Vec::new();
3856        let mut minimum_version = "3.6".to_string(); // Default modern minimum
3857
3858        // Check for version-specific features
3859        for patterns in self.modern_feature_patterns.values() {
3860            for pattern in patterns {
3861                if pattern.pattern.is_match(content) {
3862                    let version_required = pattern.python_version.clone();
3863
3864                    // Update minimum version if this feature requires newer version
3865                    if self.is_newer_version(&version_required, &minimum_version) {
3866                        minimum_version = version_required.clone();
3867                    }
3868
3869                    features_by_version.push(VersionFeature {
3870                        feature_name: pattern.name.clone(),
3871                        python_version: version_required,
3872                        usage_count: pattern.pattern.find_iter(content).count(),
3873                        is_best_practice: matches!(
3874                            pattern.complexity,
3875                            FeatureComplexity::Simple | FeatureComplexity::Moderate
3876                        ),
3877                    });
3878                }
3879            }
3880        }
3881
3882        // Check for compatibility issues
3883        if content.contains("print ") && !content.contains("print(") {
3884            compatibility_issues.push(CompatibilityIssue {
3885                issue_type: CompatibilityIssueType::SyntaxError,
3886                severity: CompatibilitySeverity::Critical,
3887                feature_name: "Print Statement".to_string(),
3888                required_version: "2.x".to_string(),
3889                description: "Print statement syntax not supported in Python 3".to_string(),
3890                recommendation: "Use print() function instead".to_string(),
3891            });
3892        }
3893
3894        PythonVersionDetected {
3895            minimum_version,
3896            features_by_version,
3897            compatibility_issues,
3898        }
3899    }
3900
3901    /// Helper methods for modern feature analysis
3902    fn extract_dataclass_name(&self, _match: &str, content: &str) -> String {
3903        // Look for class definition near the dataclass decorator
3904        if let Some(class_match) = Regex::new(r"class\s+(\w+)").unwrap().find(content) {
3905            if let Some(captures) = Regex::new(r"class\s+(\w+)")
3906                .unwrap()
3907                .captures(class_match.as_str())
3908            {
3909                return captures.get(1).unwrap().as_str().to_string();
3910            }
3911        }
3912        "UnknownClass".to_string()
3913    }
3914
3915    fn analyze_dataclass_fields(&self, content: &str, class_name: &str) -> Vec<DataclassField> {
3916        // Simplified field analysis - in production this would parse the class body
3917        let mut fields = Vec::new();
3918
3919        // Look for field annotations in the class
3920        let field_regex = Regex::new(&format!(r"class\s+{}.*?(\w+):\s*(\w+)", class_name)).unwrap();
3921        for captures in field_regex.captures_iter(content) {
3922            if captures.len() >= 3 {
3923                let field_name = captures.get(1).unwrap().as_str().to_string();
3924                let field_type = captures.get(2).unwrap().as_str().to_string();
3925
3926                fields.push(DataclassField {
3927                    name: field_name,
3928                    field_type,
3929                    has_default: false,
3930                    is_optional: false,
3931                    validation_rules: Vec::new(),
3932                    metadata: Vec::new(),
3933                });
3934            }
3935        }
3936
3937        fields
3938    }
3939
3940    fn detect_dataclass_features(&self, content: &str, _class_name: &str) -> Vec<DataclassFeature> {
3941        let mut features = Vec::new();
3942
3943        if content.contains("frozen=True") {
3944            features.push(DataclassFeature::FrozenClass);
3945        }
3946        if content.contains("__slots__") {
3947            features.push(DataclassFeature::SlotsUsage);
3948        }
3949        if content.contains("__post_init__") {
3950            features.push(DataclassFeature::PostInitProcessing);
3951        }
3952        if content.contains("default_factory") {
3953            features.push(DataclassFeature::FieldFactories);
3954        }
3955
3956        features
3957    }
3958
3959    fn assess_dataclass_complexity(
3960        &self,
3961        fields: &[DataclassField],
3962        features: &[DataclassFeature],
3963    ) -> FeatureComplexity {
3964        let complexity_score = fields.len() + features.len() * 2;
3965
3966        match complexity_score {
3967            0..=3 => FeatureComplexity::Simple,
3968            4..=8 => FeatureComplexity::Moderate,
3969            9..=15 => FeatureComplexity::Complex,
3970            _ => FeatureComplexity::Expert,
3971        }
3972    }
3973
3974    fn score_dataclass_best_practices(
3975        &self,
3976        _fields: &[DataclassField],
3977        features: &[DataclassFeature],
3978    ) -> i32 {
3979        let mut score = 60; // Base score
3980
3981        // Add points for good practices
3982        if features.contains(&DataclassFeature::FrozenClass) {
3983            score += 15; // Immutability is good
3984        }
3985        if features.contains(&DataclassFeature::SlotsUsage) {
3986            score += 10; // Memory optimization
3987        }
3988        if features.contains(&DataclassFeature::PostInitProcessing) {
3989            score += 10; // Proper initialization
3990        }
3991
3992        score.min(100)
3993    }
3994
3995    fn get_dataclass_recommendations(
3996        &self,
3997        features: &[DataclassFeature],
3998        score: i32,
3999    ) -> Vec<String> {
4000        let mut recommendations = Vec::new();
4001
4002        if score < 70 {
4003            recommendations.push("Consider using dataclass best practices".to_string());
4004        }
4005
4006        if !features.contains(&DataclassFeature::SlotsUsage) {
4007            recommendations.push("Consider using __slots__ for memory optimization".to_string());
4008        }
4009
4010        if !features.contains(&DataclassFeature::FrozenClass) {
4011            recommendations.push("Consider making dataclass frozen for immutability".to_string());
4012        }
4013
4014        recommendations
4015    }
4016
4017    /// Calculate overall modernity score
4018    #[allow(clippy::too_many_arguments)] // Complex analysis requires multiple feature sets
4019    fn calculate_modernity_score(
4020        &self,
4021        dataclass_features: &[DataclassInfo],
4022        context_manager_features: &[ContextManagerInfo],
4023        fstring_features: &[FStringInfo],
4024        pattern_matching_features: &[PatternMatchingInfo],
4025        generator_features: &[GeneratorInfo],
4026        decorator_features: &[ModernDecoratorInfo],
4027        modern_syntax_features: &[ModernSyntaxInfo],
4028    ) -> i32 {
4029        let mut score = 50i32; // Base score
4030
4031        // Add points for modern features
4032        score += (dataclass_features.len() * 8).min(20) as i32;
4033        score += (context_manager_features.len() * 5).min(15) as i32;
4034        score += (fstring_features.len() * 3).min(10) as i32;
4035        score += (pattern_matching_features.len() * 10).min(20) as i32;
4036        score += (generator_features.len() * 4).min(12) as i32;
4037        score += (decorator_features.len() * 2).min(10) as i32;
4038        score += (modern_syntax_features.len() * 3).min(13) as i32;
4039
4040        score.min(100)
4041    }
4042
4043    /// Generate modern feature recommendations
4044    #[allow(clippy::too_many_arguments)] // Complex analysis requires multiple feature sets
4045    fn get_modern_feature_recommendations(
4046        &self,
4047        dataclass_features: &[DataclassInfo],
4048        context_manager_features: &[ContextManagerInfo],
4049        fstring_features: &[FStringInfo],
4050        _pattern_matching_features: &[PatternMatchingInfo],
4051        generator_features: &[GeneratorInfo],
4052        _decorator_features: &[ModernDecoratorInfo],
4053        modern_syntax_features: &[ModernSyntaxInfo],
4054        python_version: &PythonVersionDetected,
4055    ) -> Vec<String> {
4056        let mut recommendations = Vec::new();
4057
4058        if dataclass_features.is_empty() {
4059            recommendations.push(
4060                "Consider using @dataclass for data classes instead of manual __init__".to_string(),
4061            );
4062        }
4063
4064        if context_manager_features.is_empty() {
4065            recommendations
4066                .push("Use context managers (with statements) for resource management".to_string());
4067        }
4068
4069        if fstring_features.is_empty() {
4070            recommendations.push(
4071                "Consider using f-strings for string formatting instead of .format()".to_string(),
4072            );
4073        }
4074
4075        if generator_features.is_empty() {
4076            recommendations
4077                .push("Consider using generators for memory-efficient iteration".to_string());
4078        }
4079
4080        // Version-specific recommendations
4081        if self.is_version_supported("3.10", &python_version.minimum_version) {
4082            recommendations.push(
4083                "Consider using pattern matching (match/case) for complex conditionals".to_string(),
4084            );
4085        }
4086
4087        if self.is_version_supported("3.8", &python_version.minimum_version) {
4088            let has_walrus = modern_syntax_features
4089                .iter()
4090                .any(|f| matches!(f.feature_type, ModernSyntaxType::WalrusOperator));
4091            if !has_walrus {
4092                recommendations.push(
4093                    "Consider using walrus operator (:=) for assignment expressions".to_string(),
4094                );
4095            }
4096        }
4097
4098        recommendations
4099    }
4100
4101    /// Analyze context usage pattern
4102    fn analyze_context_usage_pattern(
4103        &self,
4104        content: &str,
4105        _context_match: &str,
4106    ) -> ContextUsagePattern {
4107        if content.contains("async with") {
4108            ContextUsagePattern::AsyncContext
4109        } else if content.matches("with").count() > 1 {
4110            ContextUsagePattern::MultipleContexts
4111        } else {
4112            ContextUsagePattern::SingleContext
4113        }
4114    }
4115
4116    /// Assess resource management quality
4117    fn assess_resource_management_quality(
4118        &self,
4119        content: &str,
4120        _context_match: &str,
4121    ) -> ResourceManagementQuality {
4122        let has_error_handling = content.contains("try") || content.contains("except");
4123        let has_finally = content.contains("finally");
4124        let has_proper_cleanup = content.contains("close()") || content.contains("__exit__");
4125
4126        match (has_error_handling, has_finally, has_proper_cleanup) {
4127            (true, true, true) => ResourceManagementQuality::Excellent,
4128            (true, _, true) => ResourceManagementQuality::Good,
4129            (true, _, _) => ResourceManagementQuality::Adequate,
4130            (false, _, true) => ResourceManagementQuality::Poor,
4131            _ => ResourceManagementQuality::Dangerous,
4132        }
4133    }
4134
4135    /// Assess context error handling
4136    fn assess_context_error_handling(
4137        &self,
4138        content: &str,
4139        _context_match: &str,
4140    ) -> ContextErrorHandling {
4141        if content.contains("except") && content.contains("finally") {
4142            ContextErrorHandling::Comprehensive
4143        } else if content.contains("except") {
4144            ContextErrorHandling::Basic
4145        } else if content.contains("try") {
4146            ContextErrorHandling::Minimal
4147        } else {
4148            ContextErrorHandling::None
4149        }
4150    }
4151
4152    /// Calculate context nesting level
4153    fn calculate_context_nesting_level(&self, content: &str, _context_match: &str) -> usize {
4154        // Count nested with statements (simplified)
4155        let with_count = content.matches("with").count();
4156        if with_count > 3 {
4157            3 // Cap at 3 for simplicity
4158        } else {
4159            with_count
4160        }
4161    }
4162
4163    /// Check context best practices
4164    fn check_context_best_practices(&self, content: &str, _context_match: &str) -> bool {
4165        // Check for good practices
4166        let has_appropriate_error_handling = content.contains("except");
4167        let not_overly_nested = self.calculate_context_nesting_level(content, _context_match) <= 2;
4168        let has_resource_cleanup = content.contains("close") || content.contains("__exit__");
4169
4170        has_appropriate_error_handling && not_overly_nested && has_resource_cleanup
4171    }
4172
4173    /// Helper methods for f-string analysis
4174    fn assess_fstring_complexity(&self, expression: &str) -> FStringComplexity {
4175        let brace_count = expression.matches('{').count();
4176        let has_function_calls = expression.contains('(');
4177        let has_format_spec = expression.contains(':');
4178
4179        match (brace_count, has_function_calls, has_format_spec) {
4180            (1, false, false) => FStringComplexity::Simple,
4181            (1..=2, _, true) | (1..=2, true, _) => FStringComplexity::Moderate,
4182            (3..=5, _, _) => FStringComplexity::Complex,
4183            _ => FStringComplexity::Advanced,
4184        }
4185    }
4186
4187    fn detect_fstring_features(&self, expression: &str) -> Vec<FStringFeature> {
4188        let mut features = Vec::new();
4189
4190        if expression.contains('{') && expression.contains('}') {
4191            features.push(FStringFeature::BasicInterpolation);
4192        }
4193        if expression.contains('(') {
4194            features.push(FStringFeature::ExpressionEvaluation);
4195        }
4196        if expression.contains(':') {
4197            features.push(FStringFeature::FormatSpecifiers);
4198        }
4199        if expression.contains('!') {
4200            features.push(FStringFeature::ConversionFlags);
4201        }
4202        if expression.starts_with("rf") || expression.starts_with("fr") {
4203            features.push(FStringFeature::RawFString);
4204        }
4205
4206        features
4207    }
4208
4209    fn assess_fstring_performance(
4210        &self,
4211        _expression: &str,
4212        features: &[FStringFeature],
4213    ) -> PerformanceImpact {
4214        if features.contains(&FStringFeature::ComplexExpressions) {
4215            PerformanceImpact::Negative
4216        } else if features.contains(&FStringFeature::ExpressionEvaluation) {
4217            PerformanceImpact::Neutral
4218        } else {
4219            PerformanceImpact::Positive
4220        }
4221    }
4222
4223    fn assess_formatting_quality(&self, expression: &str) -> FormattingQuality {
4224        let length = expression.len();
4225        let complexity = self.assess_fstring_complexity(expression);
4226
4227        match (length, complexity) {
4228            (0..=50, FStringComplexity::Simple) => FormattingQuality::Excellent,
4229            (0..=100, FStringComplexity::Moderate) => FormattingQuality::Good,
4230            (0..=150, FStringComplexity::Complex) => FormattingQuality::Adequate,
4231            (0..=200, _) => FormattingQuality::Poor,
4232            _ => FormattingQuality::Unreadable,
4233        }
4234    }
4235
4236    fn calculate_fstring_readability(&self, expression: &str) -> i32 {
4237        let mut score = 100;
4238
4239        if expression.len() > 100 {
4240            score -= 20;
4241        }
4242        if expression.matches('{').count() > 3 {
4243            score -= 15;
4244        }
4245        if expression.contains("()") {
4246            score -= 10;
4247        }
4248
4249        score.max(0)
4250    }
4251
4252    /// Version comparison helper
4253    fn is_newer_version(&self, version1: &str, version2: &str) -> bool {
4254        // Simple version comparison (would be more sophisticated in production)
4255        let v1 = version1.trim_end_matches('+');
4256        let v2 = version2.trim_end_matches('+');
4257        v1 > v2
4258    }
4259
4260    fn is_version_supported(&self, required: &str, current: &str) -> bool {
4261        // Check if current version supports the required version
4262        self.is_newer_version(current, required) || current == required
4263    }
4264
4265    /// Pattern matching helper methods
4266    fn analyze_match_patterns(&self, match_statement: &str) -> Vec<PatternType> {
4267        let mut patterns = Vec::new();
4268
4269        if match_statement.contains("case _:") {
4270            patterns.push(PatternType::WildcardPattern);
4271        }
4272        if match_statement.contains("case ") && match_statement.contains("if ") {
4273            patterns.push(PatternType::GuardedPattern);
4274        }
4275        if match_statement.contains("case [") {
4276            patterns.push(PatternType::SequencePattern);
4277        }
4278        if match_statement.contains("case {") {
4279            patterns.push(PatternType::MappingPattern);
4280        }
4281        if match_statement.contains(" | ") {
4282            patterns.push(PatternType::OrPattern);
4283        }
4284
4285        if patterns.is_empty() {
4286            patterns.push(PatternType::LiteralPattern);
4287        }
4288
4289        patterns
4290    }
4291
4292    fn assess_pattern_complexity(&self, patterns: &[PatternType]) -> PatternComplexity {
4293        let complexity_score = patterns.len()
4294            + patterns
4295                .iter()
4296                .map(|p| match p {
4297                    PatternType::GuardedPattern => 3,
4298                    PatternType::SequencePattern | PatternType::MappingPattern => 2,
4299                    PatternType::OrPattern => 2,
4300                    _ => 1,
4301                })
4302                .sum::<usize>();
4303
4304        match complexity_score {
4305            0..=3 => PatternComplexity::Simple,
4306            4..=8 => PatternComplexity::Moderate,
4307            9..=15 => PatternComplexity::Complex,
4308            _ => PatternComplexity::Advanced,
4309        }
4310    }
4311
4312    fn check_pattern_exhaustiveness(&self, match_statement: &str) -> bool {
4313        match_statement.contains("case _:") || match_statement.contains("case default:")
4314    }
4315
4316    fn assess_match_performance(
4317        &self,
4318        patterns: &[PatternType],
4319        _match_statement: &str,
4320    ) -> MatchPerformance {
4321        let has_complex_patterns = patterns.iter().any(|p| {
4322            matches!(
4323                p,
4324                PatternType::GuardedPattern
4325                    | PatternType::SequencePattern
4326                    | PatternType::MappingPattern
4327            )
4328        });
4329
4330        if has_complex_patterns && patterns.len() > 10 {
4331            MatchPerformance::Poor
4332        } else if has_complex_patterns {
4333            MatchPerformance::Fair
4334        } else if patterns.len() <= 5 {
4335            MatchPerformance::Optimal
4336        } else {
4337            MatchPerformance::Good
4338        }
4339    }
4340
4341    fn score_pattern_best_practices(
4342        &self,
4343        patterns: &[PatternType],
4344        has_guards: bool,
4345        is_exhaustive: bool,
4346    ) -> i32 {
4347        let mut score = 70;
4348
4349        if is_exhaustive {
4350            score += 20;
4351        }
4352        if has_guards {
4353            score += 10; // Guards can be good for complex logic
4354        }
4355        if patterns.len() <= 5 {
4356            score += 10; // Simple patterns are better
4357        }
4358
4359        score.min(100)
4360    }
4361
4362    /// Generator helper methods
4363    fn classify_generator_usage_pattern(
4364        &self,
4365        content: &str,
4366        _generator_match: &str,
4367    ) -> GeneratorUsagePattern {
4368        if content.contains("yield from") {
4369            GeneratorUsagePattern::Pipeline
4370        } else if content.contains("while True") {
4371            GeneratorUsagePattern::InfiniteSequence
4372        } else if content.contains("map") || content.contains("filter") {
4373            GeneratorUsagePattern::DataTransformation
4374        } else {
4375            GeneratorUsagePattern::SimpleIteration
4376        }
4377    }
4378
4379    fn assess_generator_memory_efficiency(
4380        &self,
4381        content: &str,
4382        _generator_match: &str,
4383    ) -> MemoryEfficiency {
4384        let has_large_data_structures =
4385            content.contains("list(") || content.contains("[") && content.len() > 100;
4386        let uses_yield_properly = content.contains("yield") && !content.contains("return [");
4387
4388        match (uses_yield_properly, has_large_data_structures) {
4389            (true, false) => MemoryEfficiency::Excellent,
4390            (true, true) => MemoryEfficiency::Good,
4391            (false, false) => MemoryEfficiency::Adequate,
4392            (false, true) => MemoryEfficiency::Poor,
4393        }
4394    }
4395
4396    fn assess_generator_complexity(
4397        &self,
4398        content: &str,
4399        _generator_match: &str,
4400    ) -> GeneratorComplexity {
4401        let yield_count = content.matches("yield").count();
4402        let has_complex_logic = content.contains("if") && content.contains("for");
4403        let has_nested_loops = content.matches("for").count() > 1;
4404
4405        match (yield_count, has_complex_logic, has_nested_loops) {
4406            (1, false, false) => GeneratorComplexity::Simple,
4407            (1..=3, _, false) => GeneratorComplexity::Moderate,
4408            (_, true, true) => GeneratorComplexity::Advanced,
4409            _ => GeneratorComplexity::Complex,
4410        }
4411    }
4412
4413    fn analyze_yield_usage(&self, content: &str, _generator_match: &str) -> YieldAnalysis {
4414        YieldAnalysis {
4415            yield_count: content.matches("yield").count(),
4416            has_yield_from: content.contains("yield from"),
4417            has_send_values: content.contains(".send("),
4418            has_throw_values: content.contains(".throw("),
4419            has_close_handling: content.contains(".close("),
4420        }
4421    }
4422
4423    fn identify_generator_optimizations(
4424        &self,
4425        content: &str,
4426        _generator_match: &str,
4427    ) -> Vec<String> {
4428        let mut optimizations = Vec::new();
4429
4430        if content.contains("list(") && content.contains("yield") {
4431            optimizations.push("Avoid converting generator to list unless necessary".to_string());
4432        }
4433
4434        if content.matches("for").count() > 2 {
4435            optimizations
4436                .push("Consider breaking complex generator into smaller functions".to_string());
4437        }
4438
4439        if !content.contains("yield from") && content.contains("for") && content.contains("yield") {
4440            optimizations
4441                .push("Consider using 'yield from' for delegating to sub-generators".to_string());
4442        }
4443
4444        optimizations
4445    }
4446
4447    /// Decorator helper methods
4448    fn classify_decorator_category(&self, decorator_name: &str) -> DecoratorCategory {
4449        match decorator_name {
4450            "property" | "staticmethod" | "classmethod" => DecoratorCategory::BuiltIn,
4451            "wraps" | "singledispatch" | "cache" | "lru_cache" => {
4452                DecoratorCategory::FunctoolsDecorator
4453            }
4454            "app.route" | "api.route" | "route" => DecoratorCategory::WebFramework,
4455            "pytest.fixture" | "pytest.mark" | "unittest.mock" => DecoratorCategory::Testing,
4456            "dataclass" | "validator" => DecoratorCategory::DataValidation,
4457            _ => DecoratorCategory::Custom,
4458        }
4459    }
4460
4461    fn analyze_decorator_usage_pattern(
4462        &self,
4463        content: &str,
4464        decorator: &str,
4465    ) -> DecoratorUsagePattern {
4466        let decorator_context = self.get_decorator_context(content, decorator);
4467
4468        if decorator_context.contains('@') && decorator_context.matches('@').count() > 1 {
4469            DecoratorUsagePattern::StackedDecorators
4470        } else if decorator.contains('(') {
4471            DecoratorUsagePattern::ParameterizedDecorator
4472        } else {
4473            DecoratorUsagePattern::SingleDecorator
4474        }
4475    }
4476
4477    fn get_decorator_context(&self, content: &str, decorator: &str) -> String {
4478        // Get surrounding context for the decorator
4479        if let Some(pos) = content.find(decorator) {
4480            let start = pos.saturating_sub(100);
4481            let end = (pos + decorator.len() + 100).min(content.len());
4482            content[start..end].to_string()
4483        } else {
4484            decorator.to_string()
4485        }
4486    }
4487
4488    fn assess_decorator_complexity(&self, decorator: &str) -> DecoratorComplexity {
4489        if decorator.contains('(') && decorator.contains(',') {
4490            DecoratorComplexity::Complex
4491        } else if decorator.contains('(') {
4492            DecoratorComplexity::Moderate
4493        } else {
4494            DecoratorComplexity::Simple
4495        }
4496    }
4497
4498    fn score_decorator_best_practices(
4499        &self,
4500        category: &DecoratorCategory,
4501        usage_pattern: &DecoratorUsagePattern,
4502    ) -> i32 {
4503        let mut score = 80;
4504
4505        match category {
4506            DecoratorCategory::BuiltIn => score += 10,
4507            DecoratorCategory::FunctoolsDecorator => score += 15,
4508            DecoratorCategory::Performance => score += 10,
4509            _ => {}
4510        }
4511
4512        match usage_pattern {
4513            DecoratorUsagePattern::SingleDecorator => score += 5,
4514            DecoratorUsagePattern::StackedDecorators => score -= 5, // Can be complex
4515            _ => {}
4516        }
4517
4518        score.min(100)
4519    }
4520
4521    /// Modern syntax helper methods
4522    fn assess_syntax_complexity(&self, content: &str, pattern: &Regex) -> SyntaxComplexity {
4523        let usage_count = pattern.find_iter(content).count();
4524        let total_lines = content.lines().count();
4525        let usage_density = if total_lines > 0 {
4526            usage_count as f32 / total_lines as f32
4527        } else {
4528            0.0
4529        };
4530
4531        match usage_density {
4532            d if d > 0.1 => SyntaxComplexity::Expert,
4533            d if d > 0.05 => SyntaxComplexity::Complex,
4534            d if d > 0.01 => SyntaxComplexity::Moderate,
4535            _ => SyntaxComplexity::Simple,
4536        }
4537    }
4538
4539    fn check_syntax_best_practices(&self, content: &str, feature_type: &ModernSyntaxType) -> bool {
4540        match feature_type {
4541            ModernSyntaxType::WalrusOperator => {
4542                // Check if walrus operator is used appropriately (not overused)
4543                content.matches(":=").count() <= content.lines().count() / 10
4544            }
4545            ModernSyntaxType::PositionalOnlyParams => {
4546                // Check if positional-only parameters are used with good reason
4547                content.contains("def ") && content.contains("/")
4548            }
4549            ModernSyntaxType::TypeUnionOperator => {
4550                // Check if union operator is used instead of typing.Union
4551                !content.contains("typing.Union") || content.contains(" | ")
4552            }
4553            _ => true, // Default to good practices for other features
4554        }
4555    }
4556
4557    fn get_syntax_migration_suggestions(
4558        &self,
4559        feature_type: &ModernSyntaxType,
4560        usage_count: usize,
4561    ) -> Vec<String> {
4562        let mut suggestions = Vec::new();
4563
4564        match feature_type {
4565            ModernSyntaxType::WalrusOperator => {
4566                if usage_count > 10 {
4567                    suggestions.push(
4568                        "Consider if all walrus operator usages improve readability".to_string(),
4569                    );
4570                }
4571                suggestions.push(
4572                    "Use walrus operator to reduce code duplication in conditions".to_string(),
4573                );
4574            }
4575            ModernSyntaxType::GenericTypeHints => {
4576                suggestions.push(
4577                    "Migrate from typing.List/Dict to built-in list/dict for type hints"
4578                        .to_string(),
4579                );
4580            }
4581            ModernSyntaxType::TypeUnionOperator => {
4582                suggestions.push(
4583                    "Replace typing.Union with | operator for cleaner type hints".to_string(),
4584                );
4585            }
4586            _ => {}
4587        }
4588
4589        suggestions
4590    }
4591
4592    /// Analyze async functions in detail
4593    fn analyze_async_functions(&self, content: &str, async_functions: &mut Vec<AsyncFunctionInfo>) {
4594        for patterns in self.async_patterns.values() {
4595            for pattern in patterns {
4596                if pattern.pattern_type == "function"
4597                    || pattern.pattern_type == "generator"
4598                    || pattern.pattern_type == "context_manager"
4599                    || pattern.pattern_type == "iterator"
4600                {
4601                    for captures in pattern.pattern.captures_iter(content) {
4602                        let full_match = captures.get(0).unwrap().as_str();
4603                        let function_name = captures
4604                            .get(1)
4605                            .map(|m| m.as_str().to_string())
4606                            .unwrap_or_else(|| "anonymous".to_string());
4607
4608                        let function_type =
4609                            self.determine_async_function_type(&pattern.name, full_match);
4610                        let complexity = self.assess_async_complexity(content, full_match);
4611                        let coroutine_type = self.classify_coroutine_type(content);
4612                        let error_handling = self.assess_error_handling(content, full_match);
4613                        let has_timeout = self.has_timeout_handling(content, full_match);
4614                        let uses_context_manager =
4615                            self.uses_async_context_manager(content, full_match);
4616
4617                        async_functions.push(AsyncFunctionInfo {
4618                            name: function_name,
4619                            function_type,
4620                            complexity,
4621                            coroutine_type,
4622                            error_handling,
4623                            has_timeout,
4624                            uses_context_manager,
4625                            location: full_match.to_string(),
4626                        });
4627                    }
4628                }
4629            }
4630        }
4631    }
4632
4633    /// Analyze await usage patterns
4634    fn analyze_await_usage(&self, content: &str, await_patterns: &mut Vec<AwaitUsageInfo>) {
4635        let await_pattern = Regex::new(r"await\s+([^;\n]+)").unwrap();
4636
4637        for captures in await_pattern.captures_iter(content) {
4638            let full_match = captures.get(0).unwrap().as_str();
4639            let await_expr = captures.get(1).unwrap().as_str();
4640
4641            let context = self.determine_await_context(content, full_match);
4642            let usage_pattern = self.classify_await_usage_pattern(content, await_expr);
4643            let is_valid = self.validate_await_usage(&context);
4644            let potential_issues = self.detect_await_issues(content, await_expr, &context);
4645
4646            await_patterns.push(AwaitUsageInfo {
4647                location: full_match.to_string(),
4648                context,
4649                usage_pattern,
4650                is_valid,
4651                potential_issues,
4652            });
4653        }
4654    }
4655
4656    /// Analyze concurrency patterns
4657    fn analyze_concurrency_patterns(
4658        &self,
4659        content: &str,
4660        concurrency_patterns: &mut Vec<ConcurrencyPatternInfo>,
4661    ) {
4662        for patterns in self.async_patterns.values() {
4663            for pattern in patterns {
4664                if pattern.pattern_type == "concurrency" {
4665                    for captures in pattern.pattern.captures_iter(content) {
4666                        let full_match = captures.get(0).unwrap().as_str();
4667
4668                        let pattern_type = self.map_to_concurrency_pattern_type(&pattern.name);
4669                        let usage_quality =
4670                            self.assess_concurrency_usage_quality(content, full_match);
4671                        let best_practices_followed =
4672                            self.check_concurrency_best_practices(content, full_match);
4673
4674                        concurrency_patterns.push(ConcurrencyPatternInfo {
4675                            pattern_type,
4676                            usage_quality,
4677                            performance_impact: pattern.performance_impact.clone(),
4678                            location: full_match.to_string(),
4679                            best_practices_followed,
4680                        });
4681                    }
4682                }
4683            }
4684        }
4685    }
4686
4687    /// Detect async performance issues
4688    fn detect_async_performance_issues(
4689        &self,
4690        content: &str,
4691        issues: &mut Vec<AsyncPerformanceIssue>,
4692    ) {
4693        // Detect blocking IO in async functions - look for blocking calls within async function bodies
4694        if content.contains("async def")
4695            && (content.contains("time.sleep")
4696                || content.contains("open(")
4697                || content.contains("input("))
4698        {
4699            issues.push(AsyncPerformanceIssue {
4700                issue_type: AsyncPerformanceIssueType::BlockingIOInAsync,
4701                severity: AsyncIssueSeverity::High,
4702                location: "Async function with blocking operations".to_string(),
4703                description: "Blocking I/O operation in async function".to_string(),
4704                recommendation: "Use async I/O operations or run_in_executor".to_string(),
4705                estimated_impact: AsyncPerformanceImpact::Critical,
4706            });
4707        }
4708
4709        // Detect await in loops
4710        let await_loop_pattern = Regex::new(r"for\s+.*?:\s*.*?await\s+").unwrap();
4711        for captures in await_loop_pattern.captures_iter(content) {
4712            let full_match = captures.get(0).unwrap().as_str();
4713            issues.push(AsyncPerformanceIssue {
4714                issue_type: AsyncPerformanceIssueType::AwaitInLoop,
4715                severity: AsyncIssueSeverity::Medium,
4716                location: full_match.to_string(),
4717                description: "Sequential await in loop - consider asyncio.gather()".to_string(),
4718                recommendation:
4719                    "Use asyncio.gather() or asyncio.as_completed() for concurrent execution"
4720                        .to_string(),
4721                estimated_impact: AsyncPerformanceImpact::Negative,
4722            });
4723        }
4724
4725        // Detect missing concurrency opportunities
4726        let sequential_await_pattern = Regex::new(r"await\s+\w+.*\n.*await\s+\w+").unwrap();
4727        for captures in sequential_await_pattern.captures_iter(content) {
4728            let full_match = captures.get(0).unwrap().as_str();
4729            issues.push(AsyncPerformanceIssue {
4730                issue_type: AsyncPerformanceIssueType::MissingConcurrency,
4731                severity: AsyncIssueSeverity::Medium,
4732                location: full_match.to_string(),
4733                description: "Sequential await calls could be concurrent".to_string(),
4734                recommendation: "Consider using asyncio.gather() for independent operations"
4735                    .to_string(),
4736                estimated_impact: AsyncPerformanceImpact::Negative,
4737            });
4738        }
4739    }
4740
4741    /// Detect async security issues
4742    fn detect_async_security_issues(&self, content: &str, issues: &mut Vec<AsyncSecurityIssue>) {
4743        // Detect missing timeouts
4744        let await_pattern = Regex::new(r"await\s+").unwrap();
4745        let timeout_count = content.matches("asyncio.wait_for").count()
4746            + content.matches("asyncio.timeout").count();
4747        let await_count = await_pattern.find_iter(content).count();
4748
4749        if await_count > timeout_count + 2 {
4750            issues.push(AsyncSecurityIssue {
4751                issue_type: AsyncSecurityIssueType::AsyncTimeoutVuln,
4752                severity: AsyncSecuritySeverity::Medium,
4753                location: "Multiple async operations".to_string(),
4754                description: "Missing timeout handling in async operations".to_string(),
4755                recommendation: "Add timeouts to prevent DoS attacks".to_string(),
4756            });
4757        }
4758
4759        // Detect shared state without locking
4760        let shared_state_pattern =
4761            Regex::new(r"(?:global|class)\s+\w+.*=.*\n.*async\s+def.*\w+.*=").unwrap();
4762        for captures in shared_state_pattern.captures_iter(content) {
4763            let full_match = captures.get(0).unwrap().as_str();
4764            if !content.contains("asyncio.Lock") && !content.contains("asyncio.Semaphore") {
4765                issues.push(AsyncSecurityIssue {
4766                    issue_type: AsyncSecurityIssueType::SharedStateNoLock,
4767                    severity: AsyncSecuritySeverity::High,
4768                    location: full_match.to_string(),
4769                    description: "Shared mutable state without proper locking".to_string(),
4770                    recommendation: "Use asyncio.Lock or asyncio.Semaphore for thread safety"
4771                        .to_string(),
4772                });
4773            }
4774        }
4775
4776        // Detect race condition patterns
4777        if content.contains("asyncio.gather")
4778            && !content.contains("asyncio.Lock")
4779            && content.matches("=").count() > 3
4780        {
4781            issues.push(AsyncSecurityIssue {
4782                issue_type: AsyncSecurityIssueType::AsyncRaceCondition,
4783                severity: AsyncSecuritySeverity::Medium,
4784                location: "Concurrent operations".to_string(),
4785                description: "Potential race condition in concurrent operations".to_string(),
4786                recommendation: "Review shared resource access and add synchronization".to_string(),
4787            });
4788        }
4789    }
4790
4791    /// Detect modern async features
4792    fn detect_modern_async_features(&self, content: &str, features: &mut Vec<ModernAsyncFeature>) {
4793        let modern_patterns = &[
4794            (
4795                "async with",
4796                ModernAsyncFeatureType::AsyncContextManager,
4797                "3.7+",
4798            ),
4799            (
4800                "asyncio.TaskGroup",
4801                ModernAsyncFeatureType::TaskGroups,
4802                "3.11+",
4803            ),
4804            (
4805                "asyncio.timeout",
4806                ModernAsyncFeatureType::AsyncioTimeout,
4807                "3.11+",
4808            ),
4809            ("async for", ModernAsyncFeatureType::AsyncIterators, "3.7+"),
4810            ("contextvars", ModernAsyncFeatureType::ContextVars, "3.7+"),
4811            ("asyncio.run", ModernAsyncFeatureType::AsyncioRun, "3.7+"),
4812        ];
4813
4814        for (pattern_str, feature_type, version) in modern_patterns {
4815            let count = content.matches(pattern_str).count();
4816            if count > 0 {
4817                features.push(ModernAsyncFeature {
4818                    feature_type: feature_type.clone(),
4819                    python_version: version.to_string(),
4820                    usage_count: count,
4821                    description: format!("Modern async feature: {}", pattern_str),
4822                    is_best_practice: true,
4823                });
4824            }
4825        }
4826
4827        // Detect async comprehensions
4828        let async_comp_pattern = Regex::new(r"\[.*async\s+for.*\]|\{.*async\s+for.*\}").unwrap();
4829        let comp_count = async_comp_pattern.find_iter(content).count();
4830        if comp_count > 0 {
4831            features.push(ModernAsyncFeature {
4832                feature_type: ModernAsyncFeatureType::AsyncComprehensions,
4833                python_version: "3.6+".to_string(),
4834                usage_count: comp_count,
4835                description: "Async comprehensions for concurrent iteration".to_string(),
4836                is_best_practice: true,
4837            });
4838        }
4839    }
4840
4841    /// Helper methods for async analysis
4842    fn determine_async_function_type(
4843        &self,
4844        pattern_name: &str,
4845        _full_match: &str,
4846    ) -> AsyncFunctionType {
4847        match pattern_name {
4848            "Async Function" => AsyncFunctionType::RegularAsync,
4849            "Async Generator" => AsyncFunctionType::AsyncGenerator,
4850            "Async Context Manager" => AsyncFunctionType::AsyncContextManager,
4851            "Async Iterator" => AsyncFunctionType::AsyncIterator,
4852            _ => AsyncFunctionType::RegularAsync,
4853        }
4854    }
4855
4856    fn assess_async_complexity(&self, _content: &str, function_match: &str) -> AsyncComplexity {
4857        let await_count = function_match.matches("await").count();
4858        let try_count = function_match.matches("try").count();
4859        let gather_count = function_match.matches("gather").count();
4860
4861        match (await_count, try_count, gather_count) {
4862            (0..=1, 0, 0) => AsyncComplexity::Simple,
4863            (2..=3, 0..=1, 0..=1) => AsyncComplexity::Moderate,
4864            (4..=6, 1..=2, 0..=2) => AsyncComplexity::Complex,
4865            _ => AsyncComplexity::Advanced,
4866        }
4867    }
4868
4869    fn classify_coroutine_type(&self, content: &str) -> CoroutineType {
4870        if content.contains("asyncio") {
4871            CoroutineType::Framework("asyncio".to_string())
4872        } else if content.contains("trio") {
4873            CoroutineType::Framework("trio".to_string())
4874        } else if content.contains("curio") {
4875            CoroutineType::Framework("curio".to_string())
4876        } else if content.contains("yield from") {
4877            CoroutineType::Generator
4878        } else {
4879            CoroutineType::Native
4880        }
4881    }
4882
4883    fn assess_error_handling(&self, _content: &str, function_match: &str) -> AsyncErrorHandling {
4884        if function_match.contains("asyncio.timeout") || function_match.contains("asyncio.wait_for")
4885        {
4886            AsyncErrorHandling::Robust
4887        } else if function_match.contains("timeout") {
4888            AsyncErrorHandling::Timeout
4889        } else if function_match.contains("try") && function_match.contains("except") {
4890            AsyncErrorHandling::Basic
4891        } else {
4892            AsyncErrorHandling::None
4893        }
4894    }
4895
4896    fn has_timeout_handling(&self, _content: &str, function_match: &str) -> bool {
4897        function_match.contains("timeout") || function_match.contains("asyncio.wait_for")
4898    }
4899
4900    fn uses_async_context_manager(&self, _content: &str, function_match: &str) -> bool {
4901        function_match.contains("async with")
4902    }
4903
4904    fn determine_await_context(&self, content: &str, await_match: &str) -> AwaitContext {
4905        // Simplified context detection - in practice, would need more sophisticated parsing
4906        if content.contains("async def") {
4907            if await_match.contains("__aenter__") || await_match.contains("__aexit__") {
4908                AwaitContext::AsyncContextManager
4909            } else if await_match.contains("__aiter__") || await_match.contains("__anext__") {
4910                AwaitContext::AsyncIterator
4911            } else if await_match.contains("yield") {
4912                AwaitContext::AsyncGenerator
4913            } else {
4914                AwaitContext::AsyncFunction
4915            }
4916        } else if await_match.contains("[") && await_match.contains("for") {
4917            AwaitContext::Comprehension
4918        } else if await_match.contains("lambda") {
4919            AwaitContext::Lambda
4920        } else {
4921            AwaitContext::SyncContext
4922        }
4923    }
4924
4925    fn classify_await_usage_pattern(&self, content: &str, await_expr: &str) -> AwaitUsagePattern {
4926        if content.contains("asyncio.gather") {
4927            AwaitUsagePattern::GatheredAwait
4928        } else if await_expr.contains("await") {
4929            AwaitUsagePattern::NestedAwait
4930        } else if content.contains("if") && await_expr.contains("await") {
4931            AwaitUsagePattern::ConditionalAwait
4932        } else if content.matches("await").count() > 1 {
4933            AwaitUsagePattern::SequentialAwaits
4934        } else {
4935            AwaitUsagePattern::SingleAwait
4936        }
4937    }
4938
4939    fn validate_await_usage(&self, context: &AwaitContext) -> bool {
4940        !matches!(
4941            context,
4942            AwaitContext::SyncContext | AwaitContext::Comprehension | AwaitContext::Lambda
4943        )
4944    }
4945
4946    fn detect_await_issues(
4947        &self,
4948        content: &str,
4949        await_expr: &str,
4950        context: &AwaitContext,
4951    ) -> Vec<AwaitIssue> {
4952        let mut issues = Vec::new();
4953
4954        if !self.validate_await_usage(context) {
4955            issues.push(AwaitIssue::IllegalContext);
4956        }
4957
4958        if await_expr.contains("open(") || await_expr.contains("input(") {
4959            issues.push(AwaitIssue::BlockingCall);
4960        }
4961
4962        if !content.contains("timeout") && !content.contains("asyncio.wait_for") {
4963            issues.push(AwaitIssue::TimeoutMissing);
4964        }
4965
4966        issues
4967    }
4968
4969    fn map_to_concurrency_pattern_type(&self, pattern_name: &str) -> ConcurrencyPatternType {
4970        match pattern_name {
4971            "Asyncio Gather" => ConcurrencyPatternType::AsyncioGather,
4972            "Asyncio Wait" => ConcurrencyPatternType::AsyncioWait,
4973            "Asyncio Queue" => ConcurrencyPatternType::AsyncioQueue,
4974            "Asyncio Semaphore" => ConcurrencyPatternType::AsyncioSemaphore,
4975            "Asyncio Lock" => ConcurrencyPatternType::AsyncioLock,
4976            "TaskGroup" => ConcurrencyPatternType::TaskGroup,
4977            "Concurrent Futures" => ConcurrencyPatternType::ConcurrentFutures,
4978            "Asyncio Timeout" => ConcurrencyPatternType::AsyncioTimeout,
4979            "Asyncio Event" => ConcurrencyPatternType::AsyncioEvent,
4980            "Asyncio Condition" => ConcurrencyPatternType::AsyncioCondition,
4981            _ => ConcurrencyPatternType::AsyncioGather,
4982        }
4983    }
4984
4985    fn assess_concurrency_usage_quality(
4986        &self,
4987        content: &str,
4988        pattern_match: &str,
4989    ) -> ConcurrencyUsageQuality {
4990        let has_error_handling = pattern_match.contains("try") || pattern_match.contains("except");
4991        let has_timeout = pattern_match.contains("timeout") || content.contains("asyncio.wait_for");
4992        let has_proper_cleanup =
4993            pattern_match.contains("finally") || pattern_match.contains("async with");
4994
4995        match (has_error_handling, has_timeout, has_proper_cleanup) {
4996            (true, true, true) => ConcurrencyUsageQuality::Excellent,
4997            (true, true, false) | (true, false, true) => ConcurrencyUsageQuality::Good,
4998            (true, false, false) | (false, true, false) | (false, true, true) => {
4999                ConcurrencyUsageQuality::Adequate
5000            }
5001            (false, false, true) => ConcurrencyUsageQuality::Poor,
5002            (false, false, false) => ConcurrencyUsageQuality::Dangerous,
5003        }
5004    }
5005
5006    fn check_concurrency_best_practices(&self, content: &str, _pattern_match: &str) -> bool {
5007        content.contains("async with")
5008            && (content.contains("timeout") || content.contains("asyncio.wait_for"))
5009            && content.contains("try")
5010    }
5011
5012    fn calculate_async_score(
5013        &self,
5014        async_functions: &[AsyncFunctionInfo],
5015        concurrency_patterns: &[ConcurrencyPatternInfo],
5016        performance_issues: &[AsyncPerformanceIssue],
5017        security_issues: &[AsyncSecurityIssue],
5018    ) -> i32 {
5019        let base_score = 50;
5020
5021        // Bonus for async functions
5022        let async_bonus = async_functions.len() as i32 * 5;
5023
5024        // Bonus for good concurrency patterns
5025        let concurrency_bonus = concurrency_patterns
5026            .iter()
5027            .map(|p| match p.usage_quality {
5028                ConcurrencyUsageQuality::Excellent => 10,
5029                ConcurrencyUsageQuality::Good => 7,
5030                ConcurrencyUsageQuality::Adequate => 4,
5031                ConcurrencyUsageQuality::Poor => 1,
5032                ConcurrencyUsageQuality::Dangerous => -5,
5033            })
5034            .sum::<i32>();
5035
5036        // Penalty for issues
5037        let performance_penalty = performance_issues
5038            .iter()
5039            .map(|i| match i.severity {
5040                AsyncIssueSeverity::Critical => 20,
5041                AsyncIssueSeverity::High => 15,
5042                AsyncIssueSeverity::Medium => 10,
5043                AsyncIssueSeverity::Low => 5,
5044                AsyncIssueSeverity::Info => 1,
5045            })
5046            .sum::<i32>();
5047
5048        let security_penalty = security_issues
5049            .iter()
5050            .map(|i| match i.severity {
5051                AsyncSecuritySeverity::Critical => 25,
5052                AsyncSecuritySeverity::High => 20,
5053                AsyncSecuritySeverity::Medium => 15,
5054                AsyncSecuritySeverity::Low => 10,
5055                AsyncSecuritySeverity::Info => 5,
5056            })
5057            .sum::<i32>();
5058
5059        (base_score + async_bonus + concurrency_bonus - performance_penalty - security_penalty)
5060            .clamp(0, 100)
5061    }
5062
5063    fn get_async_recommendations(
5064        &self,
5065        async_functions: &[AsyncFunctionInfo],
5066        await_patterns: &[AwaitUsageInfo],
5067        concurrency_patterns: &[ConcurrencyPatternInfo],
5068        performance_issues: &[AsyncPerformanceIssue],
5069        security_issues: &[AsyncSecurityIssue],
5070    ) -> Vec<String> {
5071        let mut recommendations = Vec::new();
5072
5073        if async_functions.is_empty() {
5074            recommendations.push("Consider using async/await for I/O bound operations".to_string());
5075        }
5076
5077        if !performance_issues.is_empty() {
5078            recommendations
5079                .push("Address async performance issues for better efficiency".to_string());
5080        }
5081
5082        if !security_issues.is_empty() {
5083            recommendations.push("Fix async security vulnerabilities".to_string());
5084        }
5085
5086        let has_poor_concurrency = concurrency_patterns.iter().any(|p| {
5087            matches!(
5088                p.usage_quality,
5089                ConcurrencyUsageQuality::Poor | ConcurrencyUsageQuality::Dangerous
5090            )
5091        });
5092
5093        if has_poor_concurrency {
5094            recommendations
5095                .push("Improve concurrency pattern usage with proper error handling".to_string());
5096        }
5097
5098        let has_invalid_await = await_patterns.iter().any(|p| !p.is_valid);
5099        if has_invalid_await {
5100            recommendations.push("Fix invalid await usage in sync contexts".to_string());
5101        }
5102
5103        let missing_timeouts = async_functions.iter().any(|f| !f.has_timeout);
5104        if missing_timeouts {
5105            recommendations.push("Add timeout handling to prevent hanging operations".to_string());
5106        }
5107
5108        recommendations
5109            .push("Use asyncio.gather() for concurrent independent operations".to_string());
5110        recommendations
5111            .push("Implement proper async context managers for resource cleanup".to_string());
5112        recommendations
5113            .push("Consider using Python 3.11+ TaskGroup for structured concurrency".to_string());
5114
5115        recommendations
5116    }
5117
5118    /// Helper methods for type hint analysis
5119    fn parse_type_hint_type(&self, hint_type: &str, captures: &regex::Captures) -> TypeHintType {
5120        match hint_type {
5121            "union" => {
5122                let types_str = captures.get(1).unwrap().as_str();
5123                let union_types = types_str.split(',').map(|s| s.trim().to_string()).collect();
5124                TypeHintType::UnionType(union_types)
5125            }
5126            "union_new" => {
5127                let type1 = captures.get(1).unwrap().as_str().to_string();
5128                let type2 = captures.get(2).unwrap().as_str().to_string();
5129                TypeHintType::UnionType(vec![type1, type2])
5130            }
5131            "optional" => {
5132                let inner_type = captures.get(1).unwrap().as_str().to_string();
5133                TypeHintType::OptionalType(inner_type)
5134            }
5135            "generic_list" => {
5136                let element_type = captures.get(1).unwrap().as_str().to_string();
5137                TypeHintType::GenericType(GenericTypeInfo {
5138                    base_type: "List".to_string(),
5139                    type_parameters: vec![element_type],
5140                    is_covariant: true,
5141                    is_contravariant: false,
5142                })
5143            }
5144            "generic_dict" => {
5145                let key_type = captures.get(1).unwrap().as_str().to_string();
5146                let value_type = captures.get(2).unwrap().as_str().to_string();
5147                TypeHintType::GenericType(GenericTypeInfo {
5148                    base_type: "Dict".to_string(),
5149                    type_parameters: vec![key_type, value_type],
5150                    is_covariant: false,
5151                    is_contravariant: false,
5152                })
5153            }
5154            "callable" => {
5155                let params_str = captures.get(1).unwrap().as_str();
5156                let return_type = captures.get(2).unwrap().as_str().to_string();
5157                let parameter_types = if params_str.is_empty() {
5158                    Vec::new()
5159                } else {
5160                    params_str
5161                        .split(',')
5162                        .map(|s| s.trim().to_string())
5163                        .collect()
5164                };
5165                TypeHintType::CallableType(CallableTypeInfo {
5166                    parameter_types,
5167                    return_type,
5168                    is_async: false,
5169                })
5170            }
5171            "typevar" => {
5172                let var_name = captures.get(1).unwrap().as_str().to_string();
5173                TypeHintType::TypeVarType(TypeVarInfo {
5174                    name: var_name,
5175                    bounds: Vec::new(),
5176                    constraints: Vec::new(),
5177                    covariant: false,
5178                    contravariant: false,
5179                })
5180            }
5181            "protocol" => TypeHintType::ProtocolType("Protocol".to_string()),
5182            "literal" => {
5183                let values_str = captures.get(1).unwrap().as_str();
5184                let literal_values = values_str
5185                    .split(',')
5186                    .map(|s| s.trim().to_string())
5187                    .collect();
5188                TypeHintType::LiteralType(literal_values)
5189            }
5190            "final" => {
5191                let final_type = captures.get(1).unwrap().as_str().to_string();
5192                TypeHintType::FinalType(final_type)
5193            }
5194            "typeddict" => {
5195                let class_name = captures.get(1).unwrap().as_str().to_string();
5196                TypeHintType::TypedDictType(TypedDictInfo {
5197                    name: class_name,
5198                    fields: Vec::new(), // Would need more parsing for actual fields
5199                    total: true,
5200                })
5201            }
5202            "generic_alias" => {
5203                let base_type = captures.get(1).unwrap().as_str().to_string();
5204                let element_type = captures.get(2).unwrap().as_str().to_string();
5205                TypeHintType::GenericType(GenericTypeInfo {
5206                    base_type,
5207                    type_parameters: vec![element_type],
5208                    is_covariant: true,
5209                    is_contravariant: false,
5210                })
5211            }
5212            _ => TypeHintType::SimpleType("Unknown".to_string()),
5213        }
5214    }
5215
5216    fn is_generic_type(&self, hint_type: &str) -> bool {
5217        matches!(hint_type, "generic_list" | "generic_dict" | "generic_alias")
5218    }
5219
5220    fn has_type_constraints(&self, hint_type: &str) -> bool {
5221        matches!(hint_type, "typevar" | "protocol" | "literal")
5222    }
5223
5224    fn get_modern_feature_type(&self, hint_type: &str) -> Option<ModernTypeFeatureType> {
5225        match hint_type {
5226            "union_new" => Some(ModernTypeFeatureType::UnionSyntaxPy310),
5227            "typeddict" => Some(ModernTypeFeatureType::TypedDict),
5228            "final" => Some(ModernTypeFeatureType::FinalType),
5229            "literal" => Some(ModernTypeFeatureType::LiteralType),
5230            "protocol" => Some(ModernTypeFeatureType::ProtocolType),
5231            "generic_alias" => Some(ModernTypeFeatureType::GenericAlias),
5232            _ => None,
5233        }
5234    }
5235
5236    fn detect_type_safety_issues(&self, content: &str, issues: &mut Vec<TypeSafetyIssue>) {
5237        // Detect Any type overuse
5238        let any_count = content.matches("Any").count();
5239        if any_count > 5 {
5240            issues.push(TypeSafetyIssue {
5241                issue_type: TypeSafetyIssueType::AnyTypeOveruse,
5242                severity: TypeSafetySeverity::Warning,
5243                location: "Multiple locations".to_string(),
5244                description: format!("Found {} uses of Any type", any_count),
5245                recommendation: "Consider using more specific type hints".to_string(),
5246            });
5247        }
5248
5249        // Detect missing type hints
5250        let func_pattern = Regex::new(r"def\s+\w+\s*\([^)]*\)\s*:").unwrap();
5251        let typed_func_pattern = Regex::new(r"def\s+\w+\s*\([^)]*\)\s*->\s*\w+:").unwrap();
5252
5253        let total_functions = func_pattern.find_iter(content).count();
5254        let typed_functions = typed_func_pattern.find_iter(content).count();
5255
5256        if total_functions > typed_functions && total_functions > 0 {
5257            let missing_hints = total_functions - typed_functions;
5258            issues.push(TypeSafetyIssue {
5259                issue_type: TypeSafetyIssueType::MissingTypeHints,
5260                severity: TypeSafetySeverity::Warning,
5261                location: "Function definitions".to_string(),
5262                description: format!("{} functions missing return type hints", missing_hints),
5263                recommendation: "Add return type annotations to functions".to_string(),
5264            });
5265        }
5266
5267        // Detect type: ignore overuse
5268        let ignore_count = content.matches("# type: ignore").count();
5269        if ignore_count > 3 {
5270            issues.push(TypeSafetyIssue {
5271                issue_type: TypeSafetyIssueType::TypeIgnoreOveruse,
5272                severity: TypeSafetySeverity::Info,
5273                location: "Multiple locations".to_string(),
5274                description: format!("Found {} type: ignore comments", ignore_count),
5275                recommendation: "Review and fix type issues instead of ignoring them".to_string(),
5276            });
5277        }
5278
5279        // Detect deprecated typing syntax
5280        if content.contains("typing.List") || content.contains("typing.Dict") {
5281            issues.push(TypeSafetyIssue {
5282                issue_type: TypeSafetyIssueType::DeprecatedTypingSyntax,
5283                severity: TypeSafetySeverity::Info,
5284                location: "Import statements".to_string(),
5285                description: "Using deprecated typing imports".to_string(),
5286                recommendation: "Use built-in generics (list, dict) for Python 3.9+".to_string(),
5287            });
5288        }
5289    }
5290
5291    fn calculate_type_coverage(&self, content: &str, _type_hints: &[TypeHintInfo]) -> f32 {
5292        let func_pattern = Regex::new(r"def\s+\w+").unwrap();
5293        let total_functions = func_pattern.find_iter(content).count();
5294
5295        if total_functions == 0 {
5296            return 0.0;
5297        }
5298
5299        // Count functions with type annotations (parameter or return type hints)
5300        let typed_func_pattern =
5301            Regex::new(r"def\s+\w+\s*\([^)]*:\s*\w+|def\s+\w+\s*\([^)]*\)\s*->\s*\w+").unwrap();
5302        let typed_functions = typed_func_pattern.find_iter(content).count();
5303
5304        (typed_functions as f32 / total_functions as f32) * 100.0
5305    }
5306
5307    fn get_coverage_score(&self, coverage: f32) -> TypeCoverageScore {
5308        match coverage {
5309            score if score >= 90.0 => TypeCoverageScore::Excellent,
5310            score if score >= 70.0 => TypeCoverageScore::Good,
5311            score if score >= 50.0 => TypeCoverageScore::Fair,
5312            score if score >= 30.0 => TypeCoverageScore::Poor,
5313            _ => TypeCoverageScore::Minimal,
5314        }
5315    }
5316
5317    fn get_type_hint_recommendations(
5318        &self,
5319        type_hints: &[TypeHintInfo],
5320        issues: &[TypeSafetyIssue],
5321        coverage: f32,
5322    ) -> Vec<String> {
5323        let mut recommendations = Vec::new();
5324
5325        if coverage < 70.0 {
5326            recommendations.push("Increase type hint coverage for better type safety".to_string());
5327        }
5328
5329        if !issues.is_empty() {
5330            recommendations.push("Address type safety issues identified in the code".to_string());
5331        }
5332
5333        let has_modern_features = type_hints.iter().any(|h| {
5334            h.python_version_required.starts_with("3.8")
5335                || h.python_version_required.starts_with("3.9")
5336                || h.python_version_required.starts_with("3.10")
5337        });
5338
5339        if !has_modern_features {
5340            recommendations.push("Consider using modern Python type features (3.8+)".to_string());
5341        }
5342
5343        let has_complex_types = type_hints.iter().any(|h| {
5344            matches!(
5345                h.complexity,
5346                TypeComplexity::Complex | TypeComplexity::Advanced
5347            )
5348        });
5349
5350        if has_complex_types {
5351            recommendations
5352                .push("Document complex type relationships for maintainability".to_string());
5353        }
5354
5355        if type_hints.iter().any(|h| h.is_generic) {
5356            recommendations
5357                .push("Ensure generic type constraints are properly defined".to_string());
5358        }
5359
5360        recommendations.push("Use type checkers like mypy for static type validation".to_string());
5361        recommendations.push("Consider Protocol types for structural typing".to_string());
5362
5363        recommendations
5364    }
5365
5366    /// Helper methods for security analysis
5367    fn get_security_recommendation(&self, vulnerability_type: &VulnerabilityType) -> String {
5368        match vulnerability_type {
5369            VulnerabilityType::SqlInjection => {
5370                "Use parameterized queries or ORM methods".to_string()
5371            }
5372            VulnerabilityType::CommandInjection => {
5373                "Sanitize user input and avoid shell execution".to_string()
5374            }
5375            VulnerabilityType::DeserializationAttack => {
5376                "Use safe deserialization methods like json.loads".to_string()
5377            }
5378            VulnerabilityType::HardcodedSecrets => {
5379                "Use environment variables or secret management".to_string()
5380            }
5381            _ => "Review security implementation".to_string(),
5382        }
5383    }
5384
5385    fn determine_security_level(
5386        &self,
5387        vulnerabilities: &[SecurityVulnerability],
5388        security_features: &[SecurityFeature],
5389    ) -> SecurityLevel {
5390        let critical_vulns = vulnerabilities
5391            .iter()
5392            .filter(|v| matches!(v.severity, VulnerabilitySeverity::Critical))
5393            .count();
5394        let high_vulns = vulnerabilities
5395            .iter()
5396            .filter(|v| matches!(v.severity, VulnerabilitySeverity::High))
5397            .count();
5398
5399        if critical_vulns > 0 {
5400            SecurityLevel::Vulnerable
5401        } else if high_vulns > 2 {
5402            SecurityLevel::Low
5403        } else if security_features.len() > 2 {
5404            SecurityLevel::High
5405        } else {
5406            SecurityLevel::Medium
5407        }
5408    }
5409
5410    fn get_security_recommendations(
5411        &self,
5412        vulnerabilities: &[SecurityVulnerability],
5413        _security_features: &[SecurityFeature],
5414    ) -> Vec<String> {
5415        let mut recommendations = Vec::new();
5416
5417        if !vulnerabilities.is_empty() {
5418            recommendations.push("Address security vulnerabilities identified in code".to_string());
5419        }
5420
5421        recommendations.push("Implement comprehensive input validation".to_string());
5422        recommendations.push("Use secure authentication and authorization".to_string());
5423        recommendations.push("Enable security headers and CSRF protection".to_string());
5424
5425        recommendations
5426    }
5427
5428    /// Helper methods for performance analysis
5429    fn calculate_performance_score(
5430        &self,
5431        optimizations: &[PerformanceOptimization],
5432        issues: &[PerformanceIssue],
5433    ) -> i32 {
5434        let base_score = 50;
5435        let optimization_bonus = optimizations.len() as i32 * 10;
5436        let issue_penalty = issues
5437            .iter()
5438            .map(|i| match i.severity {
5439                IssueSeverity::Critical => 20,
5440                IssueSeverity::High => 15,
5441                IssueSeverity::Medium => 10,
5442                IssueSeverity::Low => 5,
5443            })
5444            .sum::<i32>();
5445
5446        (base_score + optimization_bonus - issue_penalty).clamp(0, 100)
5447    }
5448
5449    fn get_performance_recommendations(
5450        &self,
5451        _optimizations: &[PerformanceOptimization],
5452        issues: &[PerformanceIssue],
5453    ) -> Vec<String> {
5454        let mut recommendations = Vec::new();
5455
5456        if !issues.is_empty() {
5457            recommendations.push("Address performance issues identified in code".to_string());
5458        }
5459
5460        recommendations.push("Use list comprehensions and generator expressions".to_string());
5461        recommendations.push("Implement caching for expensive operations".to_string());
5462        recommendations.push("Consider async/await for I/O operations".to_string());
5463
5464        recommendations
5465    }
5466
5467    /// Framework-specific analysis methods
5468    fn analyze_django_specifics(&self, content: &str) -> DjangoAnalysis {
5469        DjangoAnalysis {
5470            models_analysis: self.extract_django_models(content),
5471            views_analysis: self.extract_django_views(content),
5472            middleware_usage: self.extract_django_middleware(content),
5473            security_middleware: self.extract_django_security_middleware(content),
5474            signals_usage: self.extract_django_signals(content),
5475            admin_customization: content.contains("admin.site.register")
5476                || content.contains("ModelAdmin"),
5477        }
5478    }
5479
5480    fn analyze_flask_specifics(&self, content: &str) -> FlaskAnalysis {
5481        FlaskAnalysis {
5482            blueprints: self.extract_flask_blueprints(content),
5483            extensions: self.extract_flask_extensions(content),
5484            error_handlers: self.extract_flask_error_handlers(content),
5485            template_usage: content.contains("render_template"),
5486            session_management: content.contains("session["),
5487        }
5488    }
5489
5490    fn analyze_fastapi_specifics(&self, content: &str) -> FastAPIAnalysis {
5491        FastAPIAnalysis {
5492            router_usage: self.extract_fastapi_routers(content),
5493            dependency_injection: self.extract_fastapi_dependencies(content),
5494            background_tasks: content.contains("BackgroundTasks"),
5495            websocket_endpoints: self.extract_fastapi_websockets(content),
5496            middleware: self.extract_fastapi_middleware(content),
5497            response_models: self.extract_fastapi_response_models(content),
5498        }
5499    }
5500
5501    fn analyze_pytest_specifics(&self, content: &str) -> PytestAnalysis {
5502        PytestAnalysis {
5503            fixtures: self.extract_pytest_fixtures(content),
5504            parametrized_tests: self.extract_pytest_parametrized(content),
5505            markers: self.extract_pytest_markers(content),
5506            plugins: self.extract_pytest_plugins(content),
5507            coverage_setup: content.contains("pytest-cov") || content.contains("coverage"),
5508        }
5509    }
5510
5511    // Simplified extraction methods (can be enhanced with more complex parsing)
5512    fn extract_django_models(&self, content: &str) -> Vec<DjangoModelInfo> {
5513        let model_pattern = Regex::new(r"class\s+(\w+)\s*\([^)]*Model[^)]*\)").unwrap();
5514        model_pattern
5515            .captures_iter(content)
5516            .map(|captures| {
5517                let model_name = captures.get(1).unwrap().as_str().to_string();
5518                DjangoModelInfo {
5519                    name: model_name,
5520                    fields: Vec::new(), // Simplified
5521                    relationships: Vec::new(),
5522                    custom_managers: false,
5523                    meta_options: Vec::new(),
5524                }
5525            })
5526            .collect()
5527    }
5528
5529    fn extract_django_views(&self, _content: &str) -> Vec<DjangoViewInfo> {
5530        Vec::new() // Simplified implementation
5531    }
5532
5533    fn extract_django_middleware(&self, _content: &str) -> Vec<String> {
5534        Vec::new() // Simplified implementation
5535    }
5536
5537    fn extract_django_security_middleware(&self, content: &str) -> Vec<String> {
5538        let mut middleware = Vec::new();
5539        if content.contains("SecurityMiddleware") {
5540            middleware.push("SecurityMiddleware".to_string());
5541        }
5542        if content.contains("CsrfViewMiddleware") {
5543            middleware.push("CsrfViewMiddleware".to_string());
5544        }
5545        middleware
5546    }
5547
5548    fn extract_django_signals(&self, content: &str) -> Vec<String> {
5549        let mut signals = Vec::new();
5550        if content.contains("post_save") {
5551            signals.push("post_save".to_string());
5552        }
5553        if content.contains("pre_save") {
5554            signals.push("pre_save".to_string());
5555        }
5556        signals
5557    }
5558
5559    fn extract_flask_blueprints(&self, _content: &str) -> Vec<FlaskBlueprintInfo> {
5560        Vec::new() // Simplified implementation
5561    }
5562
5563    fn extract_flask_extensions(&self, content: &str) -> Vec<String> {
5564        let mut extensions = Vec::new();
5565        if content.contains("Flask-Login") {
5566            extensions.push("Flask-Login".to_string());
5567        }
5568        if content.contains("Flask-SQLAlchemy") {
5569            extensions.push("Flask-SQLAlchemy".to_string());
5570        }
5571        extensions
5572    }
5573
5574    fn extract_flask_error_handlers(&self, _content: &str) -> Vec<String> {
5575        Vec::new() // Simplified implementation
5576    }
5577
5578    fn extract_fastapi_routers(&self, _content: &str) -> Vec<FastAPIRouterInfo> {
5579        Vec::new() // Simplified implementation
5580    }
5581
5582    fn extract_fastapi_dependencies(&self, _content: &str) -> Vec<String> {
5583        Vec::new() // Simplified implementation
5584    }
5585
5586    fn extract_fastapi_websockets(&self, _content: &str) -> Vec<String> {
5587        Vec::new() // Simplified implementation
5588    }
5589
5590    fn extract_fastapi_middleware(&self, _content: &str) -> Vec<String> {
5591        Vec::new() // Simplified implementation
5592    }
5593
5594    fn extract_fastapi_response_models(&self, _content: &str) -> Vec<String> {
5595        Vec::new() // Simplified implementation
5596    }
5597
5598    fn extract_pytest_fixtures(&self, _content: &str) -> Vec<PytestFixtureInfo> {
5599        Vec::new() // Simplified implementation
5600    }
5601
5602    fn extract_pytest_parametrized(&self, _content: &str) -> Vec<String> {
5603        Vec::new() // Simplified implementation
5604    }
5605
5606    fn extract_pytest_markers(&self, _content: &str) -> Vec<String> {
5607        Vec::new() // Simplified implementation
5608    }
5609
5610    fn extract_pytest_plugins(&self, _content: &str) -> Vec<String> {
5611        Vec::new() // Simplified implementation
5612    }
5613
5614    fn get_framework_best_practices(&self, framework: &str) -> Vec<String> {
5615        match framework {
5616            "Django" => vec![
5617                "Use Django ORM instead of raw SQL".to_string(),
5618                "Implement proper authentication and authorization".to_string(),
5619                "Use Django forms for input validation".to_string(),
5620            ],
5621            "Flask" => vec![
5622                "Use blueprints for application modularity".to_string(),
5623                "Implement proper error handling".to_string(),
5624                "Use Flask-WTF for form handling".to_string(),
5625            ],
5626            "FastAPI" => vec![
5627                "Use Pydantic models for request/response validation".to_string(),
5628                "Implement proper dependency injection".to_string(),
5629                "Use async/await for I/O operations".to_string(),
5630            ],
5631            _ => Vec::new(),
5632        }
5633    }
5634
5635    /// Get Python-specific recommendations
5636    pub fn get_python_recommendations(
5637        &self,
5638        decorators: &[DecoratorInfo],
5639        metaclasses: &[MetaclassInfo],
5640        inheritance: &[InheritanceInfo],
5641    ) -> Vec<String> {
5642        let mut recommendations = Vec::new();
5643
5644        // Decorator recommendations
5645        let framework_decorators = decorators.iter().filter(|d| d.framework.is_some()).count();
5646        if framework_decorators > 0 {
5647            recommendations
5648                .push("Consider documenting framework-specific decorator behavior.".to_string());
5649        }
5650
5651        let factory_decorators = decorators.iter().filter(|d| d.is_factory).count();
5652        if factory_decorators > 0 {
5653            recommendations.push(
5654                "Factory decorators detected - ensure proper parameter validation.".to_string(),
5655            );
5656        }
5657
5658        // Metaclass recommendations
5659        if !metaclasses.is_empty() {
5660            recommendations.push(
5661                "Metaclasses detected - document their behavior and impact on subclasses."
5662                    .to_string(),
5663            );
5664            recommendations.push(
5665                "Consider if metaclass functionality could be achieved with simpler patterns."
5666                    .to_string(),
5667            );
5668        }
5669
5670        // Inheritance recommendations
5671        let diamond_inheritance = inheritance
5672            .iter()
5673            .filter(|i| i.has_diamond_inheritance)
5674            .count();
5675        if diamond_inheritance > 0 {
5676            recommendations.push(
5677                "Diamond inheritance detected - verify MRO behavior is as expected.".to_string(),
5678            );
5679        }
5680
5681        let complex_inheritance = inheritance
5682            .iter()
5683            .filter(|i| i.base_classes.len() > 2)
5684            .count();
5685        if complex_inheritance > 0 {
5686            recommendations.push(
5687                "Complex inheritance hierarchies detected - consider composition over inheritance."
5688                    .to_string(),
5689            );
5690        }
5691
5692        recommendations
5693            .push("Use type hints for better code documentation and IDE support.".to_string());
5694        recommendations.push("Consider using dataclasses for simple data containers.".to_string());
5695
5696        recommendations
5697    }
5698}
5699
5700impl Default for PythonAnalyzer {
5701    fn default() -> Self {
5702        Self::new()
5703    }
5704}
5705
5706#[cfg(test)]
5707mod tests {
5708    use super::*;
5709
5710    #[test]
5711    fn test_decorator_analysis() {
5712        let analyzer = PythonAnalyzer::new();
5713
5714        let code = "@app.route('/test')\ndef test_view():\n    pass";
5715        let decorators = analyzer.analyze_decorators(code).unwrap();
5716
5717        assert!(!decorators.is_empty());
5718        assert!(decorators.iter().any(|d| d.name == "Flask Route"));
5719    }
5720
5721    #[test]
5722    fn test_metaclass_analysis() {
5723        let analyzer = PythonAnalyzer::new();
5724
5725        let code = "class TestClass(BaseClass, metaclass=RegistryMeta):\n    pass";
5726        let metaclasses = analyzer.analyze_metaclasses(code).unwrap();
5727
5728        assert!(!metaclasses.is_empty());
5729        assert!(metaclasses.iter().any(|m| m.name == "TestClass"));
5730    }
5731
5732    #[test]
5733    fn test_inheritance_analysis() {
5734        let analyzer = PythonAnalyzer::new();
5735
5736        let code = "class Child(Parent1, Parent2):\n    pass";
5737        let inheritance = analyzer.analyze_inheritance(code).unwrap();
5738
5739        assert!(!inheritance.is_empty());
5740        assert_eq!(inheritance[0].class_name, "Child");
5741        assert_eq!(inheritance[0].base_classes.len(), 2);
5742    }
5743
5744    #[test]
5745    fn test_decorator_parameter_extraction() {
5746        let analyzer = PythonAnalyzer::new();
5747
5748        let decorator = "@app.route('/test', methods=['GET', 'POST'])";
5749        let params = analyzer.extract_decorator_parameters(decorator);
5750
5751        assert!(!params.is_empty());
5752    }
5753
5754    #[test]
5755    fn test_diamond_inheritance_detection() {
5756        let analyzer = PythonAnalyzer::new();
5757
5758        let base_classes = vec!["Parent1".to_string(), "Parent2".to_string()];
5759        assert!(analyzer.detect_diamond_inheritance(&base_classes));
5760
5761        let single_base = vec!["Parent".to_string()];
5762        assert!(!analyzer.detect_diamond_inheritance(&single_base));
5763    }
5764
5765    #[test]
5766    fn test_mixin_identification() {
5767        let analyzer = PythonAnalyzer::new();
5768
5769        let base_classes = vec![
5770            "BaseMixin".to_string(),
5771            "RegularClass".to_string(),
5772            "UtilMix".to_string(),
5773        ];
5774        let mixins = analyzer.identify_mixins(&base_classes);
5775
5776        assert_eq!(mixins.len(), 2);
5777        assert!(mixins.contains(&"BaseMixin".to_string()));
5778        assert!(mixins.contains(&"UtilMix".to_string()));
5779    }
5780
5781    #[test]
5782    fn test_type_hint_analysis() {
5783        let analyzer = PythonAnalyzer::new();
5784
5785        let code = r#"
5786from typing import List, Dict, Union, Optional, Literal, Final
5787from typing_extensions import Protocol
5788
5789def process_data(items: List[str], mapping: Dict[str, int]) -> Optional[str]:
5790    return None
5791
5792def handle_union(value: Union[str, int]) -> str:
5793    return str(value)
5794
5795class MyProtocol(Protocol):
5796    def method(self) -> None: ...
5797
5798CONSTANT: Final[str] = "value"
5799MODE: Literal["read", "write"] = "read"
5800        "#;
5801
5802        let result = analyzer.analyze_type_hints(code).unwrap();
5803
5804        assert!(!result.type_hints_detected.is_empty());
5805        assert!(result
5806            .type_hints_detected
5807            .iter()
5808            .any(|h| matches!(h.hint_type, TypeHintType::GenericType(_))));
5809        assert!(result
5810            .type_hints_detected
5811            .iter()
5812            .any(|h| matches!(h.hint_type, TypeHintType::UnionType(_))));
5813        assert!(result
5814            .type_hints_detected
5815            .iter()
5816            .any(|h| matches!(h.hint_type, TypeHintType::OptionalType(_))));
5817        assert!(result.overall_coverage > 0.0);
5818    }
5819
5820    #[test]
5821    fn test_modern_type_features() {
5822        let analyzer = PythonAnalyzer::new();
5823
5824        let code = r#"
5825from typing import Final, Literal
5826from typing_extensions import TypedDict
5827
5828class UserDict(TypedDict):
5829    name: str
5830    age: int
5831
5832CONSTANT: Final[int] = 42
5833STATUS: Literal["active", "inactive"] = "active"
5834
5835# Python 3.10+ union syntax
5836def process(value: str | int) -> str | None:
5837    return None
5838        "#;
5839
5840        let result = analyzer.analyze_type_hints(code).unwrap();
5841
5842        assert!(!result.modern_type_features.is_empty());
5843        assert!(result
5844            .modern_type_features
5845            .iter()
5846            .any(|f| matches!(f.feature_type, ModernTypeFeatureType::TypedDict)));
5847        assert!(result
5848            .modern_type_features
5849            .iter()
5850            .any(|f| matches!(f.feature_type, ModernTypeFeatureType::FinalType)));
5851        assert!(result
5852            .modern_type_features
5853            .iter()
5854            .any(|f| matches!(f.feature_type, ModernTypeFeatureType::LiteralType)));
5855    }
5856
5857    #[test]
5858    fn test_type_safety_issues() {
5859        let analyzer = PythonAnalyzer::new();
5860
5861        let code = r#"
5862from typing import Any
5863
5864def untyped_function():
5865    return "hello"
5866
5867def another_untyped():
5868    pass
5869
5870def bad_any_usage(x: Any, y: Any, z: Any, a: Any, b: Any, c: Any) -> Any:
5871    return x
5872
5873# type: ignore
5874# type: ignore  
5875# type: ignore
5876# type: ignore
5877        "#;
5878
5879        let result = analyzer.analyze_type_hints(code).unwrap();
5880
5881        assert!(!result.type_safety_issues.is_empty());
5882        assert!(result
5883            .type_safety_issues
5884            .iter()
5885            .any(|issue| matches!(issue.issue_type, TypeSafetyIssueType::AnyTypeOveruse)));
5886        assert!(result
5887            .type_safety_issues
5888            .iter()
5889            .any(|issue| matches!(issue.issue_type, TypeSafetyIssueType::MissingTypeHints)));
5890        assert!(result
5891            .type_safety_issues
5892            .iter()
5893            .any(|issue| matches!(issue.issue_type, TypeSafetyIssueType::TypeIgnoreOveruse)));
5894    }
5895
5896    #[test]
5897    fn test_type_coverage_calculation() {
5898        let analyzer = PythonAnalyzer::new();
5899
5900        // High coverage code
5901        let high_coverage_code = r#"
5902def typed_func1(x: int) -> str:
5903    return str(x)
5904
5905def typed_func2(y: str) -> int:
5906    return len(y)
5907        "#;
5908
5909        let result = analyzer.analyze_type_hints(high_coverage_code).unwrap();
5910        assert!(result.overall_coverage > 50.0);
5911        assert!(matches!(
5912            result.type_coverage_score,
5913            TypeCoverageScore::Good | TypeCoverageScore::Excellent | TypeCoverageScore::Fair
5914        ));
5915
5916        // Low coverage code
5917        let low_coverage_code = r#"
5918def untyped_func1():
5919    return "hello"
5920
5921def untyped_func2():
5922    return 42
5923
5924def typed_func(x: int) -> str:
5925    return str(x)
5926        "#;
5927
5928        let result = analyzer.analyze_type_hints(low_coverage_code).unwrap();
5929        assert!(result.overall_coverage < 100.0);
5930    }
5931
5932    #[test]
5933    fn test_async_await_analysis() {
5934        let analyzer = PythonAnalyzer::new();
5935        let content = r#"
5936import asyncio
5937
5938async def fetch_data():
5939    await asyncio.sleep(1)
5940    return "data"
5941
5942async def process_items():
5943    results = await asyncio.gather(
5944        fetch_data(),
5945        fetch_data(),
5946        fetch_data()
5947    )
5948    return results
5949
5950async def with_context():
5951    async with asyncio.timeout(5):
5952        return await fetch_data()
5953"#;
5954
5955        let result = analyzer.analyze_async_await(content).unwrap();
5956
5957        // Should detect async functions
5958        assert!(!result.async_functions_detected.is_empty());
5959        assert!(result.async_functions_detected.len() >= 3);
5960
5961        // Should detect concurrency patterns
5962        assert!(!result.concurrency_patterns.is_empty());
5963
5964        // Should detect modern async features
5965        assert!(!result.modern_async_features.is_empty());
5966
5967        // Should have a reasonable async score
5968        assert!(result.overall_async_score > 50);
5969    }
5970
5971    #[test]
5972    fn test_async_performance_issues() {
5973        let analyzer = PythonAnalyzer::new();
5974        let content = r#"
5975import asyncio
5976import time
5977
5978async def bad_function():
5979    # Blocking operations in async function
5980    time.sleep(1)
5981    with open("file.txt") as f:
5982        data = f.read()
5983    
5984    # Sequential awaits that could be concurrent
5985    result1 = await fetch_data()
5986    result2 = await fetch_data()
5987    
5988    return result1 + result2
5989
5990async def fetch_data():
5991    await asyncio.sleep(0.1)
5992    return "data"
5993"#;
5994
5995        let result = analyzer.analyze_async_await(content).unwrap();
5996
5997        // Should detect performance issues
5998        assert!(!result.async_performance_issues.is_empty());
5999
6000        // Should detect blocking operations
6001        let blocking_issues: Vec<_> = result
6002            .async_performance_issues
6003            .iter()
6004            .filter(|issue| {
6005                matches!(
6006                    issue.issue_type,
6007                    AsyncPerformanceIssueType::BlockingIOInAsync
6008                )
6009            })
6010            .collect();
6011        assert!(!blocking_issues.is_empty());
6012
6013        // Should detect missing concurrency
6014        let concurrency_issues: Vec<_> = result
6015            .async_performance_issues
6016            .iter()
6017            .filter(|issue| {
6018                matches!(
6019                    issue.issue_type,
6020                    AsyncPerformanceIssueType::MissingConcurrency
6021                )
6022            })
6023            .collect();
6024        assert!(!concurrency_issues.is_empty());
6025    }
6026
6027    #[test]
6028    fn test_async_security_issues() {
6029        let analyzer = PythonAnalyzer::new();
6030        let content = r#"
6031import asyncio
6032
6033shared_data = {}
6034
6035async def unsafe_function():
6036    # No timeout handling
6037    await some_external_service()
6038    
6039    # Shared state modification without locking
6040    shared_data["key"] = "value"
6041    
6042    # Multiple concurrent operations without proper synchronization
6043    await asyncio.gather(
6044        modify_shared_data(),
6045        modify_shared_data(),
6046        modify_shared_data()
6047    )
6048
6049async def some_external_service():
6050    await asyncio.sleep(1)
6051
6052async def modify_shared_data():
6053    shared_data["counter"] = shared_data.get("counter", 0) + 1
6054"#;
6055
6056        let result = analyzer.analyze_async_await(content).unwrap();
6057
6058        // Should detect security issues
6059        assert!(!result.async_security_issues.is_empty());
6060
6061        // Should detect timeout vulnerability
6062        let timeout_issues: Vec<_> = result
6063            .async_security_issues
6064            .iter()
6065            .filter(|issue| matches!(issue.issue_type, AsyncSecurityIssueType::AsyncTimeoutVuln))
6066            .collect();
6067        assert!(!timeout_issues.is_empty());
6068    }
6069
6070    #[test]
6071    fn test_modern_async_features() {
6072        let analyzer = PythonAnalyzer::new();
6073        let content = r#"
6074import asyncio
6075import contextvars
6076
6077async def modern_async():
6078    # Modern async features
6079    async with asyncio.timeout(5):
6080        data = await fetch_data()
6081    
6082    # Async comprehension
6083    results = [await process(item) async for item in async_generator()]
6084    
6085    # Context variables
6086    context_var = contextvars.ContextVar('user_id')
6087    
6088    # TaskGroup (Python 3.11+)
6089    async with asyncio.TaskGroup() as tg:
6090        task1 = tg.create_task(fetch_data())
6091        task2 = tg.create_task(fetch_data())
6092    
6093    return results
6094
6095async def async_generator():
6096    for i in range(3):
6097        yield f"item_{i}"
6098
6099async def fetch_data():
6100    return "data"
6101
6102async def process(item):
6103    return f"processed_{item}"
6104
6105if __name__ == "__main__":
6106    asyncio.run(modern_async())
6107"#;
6108
6109        let result = analyzer.analyze_async_await(content).unwrap();
6110
6111        // Should detect modern async features
6112        assert!(!result.modern_async_features.is_empty());
6113
6114        // Should detect async context managers
6115        let context_manager_features: Vec<_> = result
6116            .modern_async_features
6117            .iter()
6118            .filter(|f| matches!(f.feature_type, ModernAsyncFeatureType::AsyncContextManager))
6119            .collect();
6120        assert!(!context_manager_features.is_empty());
6121
6122        // Should detect TaskGroups
6123        let task_group_features: Vec<_> = result
6124            .modern_async_features
6125            .iter()
6126            .filter(|f| matches!(f.feature_type, ModernAsyncFeatureType::TaskGroups))
6127            .collect();
6128        assert!(!task_group_features.is_empty());
6129
6130        // Should detect asyncio.run
6131        let asyncio_run_features: Vec<_> = result
6132            .modern_async_features
6133            .iter()
6134            .filter(|f| matches!(f.feature_type, ModernAsyncFeatureType::AsyncioRun))
6135            .collect();
6136        assert!(!asyncio_run_features.is_empty());
6137
6138        // Should have recommendations
6139        assert!(!result.recommendations.is_empty());
6140    }
6141
6142    #[test]
6143    fn test_package_dependency_analysis() {
6144        let analyzer = PythonAnalyzer::new();
6145        let content = r#"
6146import requests
6147import pandas as pd
6148from flask import Flask
6149import numpy
6150from django.db import models
6151
6152django>=3.2.0
6153requests==2.28.1
6154pandas>=1.5.0
6155numpy
6156flask==2.0.1
6157"#;
6158
6159        let result = analyzer.analyze_package_dependencies(content).unwrap();
6160
6161        // Should detect dependencies
6162        assert!(!result.dependencies.is_empty());
6163
6164        // Should detect imports
6165        assert!(!result.import_analysis.is_empty());
6166        assert!(result.import_analysis.len() >= 5);
6167
6168        // Should have a reasonable health score
6169        assert!(result.overall_health_score >= 0);
6170        assert!(result.overall_health_score <= 100);
6171
6172        // Should detect issues
6173        assert!(!result.dependency_issues.is_empty());
6174
6175        // Should provide recommendations
6176        assert!(!result.recommendations.is_empty());
6177    }
6178
6179    #[test]
6180    fn test_dependency_issue_detection() {
6181        let analyzer = PythonAnalyzer::new();
6182        let content = r#"
6183import requests
6184import missing_package
6185from some_package import *
6186
6187# Requirements:
6188requests==2.28.1
6189unused_package==1.0.0
6190imp==1.0.0
6191django
6192"#;
6193
6194        let result = analyzer.analyze_package_dependencies(content).unwrap();
6195
6196        // Should detect unused dependency
6197        let unused_issues: Vec<_> = result
6198            .dependency_issues
6199            .iter()
6200            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::UnusedDependency))
6201            .collect();
6202        assert!(!unused_issues.is_empty());
6203
6204        // Should detect missing dependency
6205        let missing_issues: Vec<_> = result
6206            .dependency_issues
6207            .iter()
6208            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::MissingDependency))
6209            .collect();
6210        assert!(!missing_issues.is_empty());
6211
6212        // Should detect unpinned version
6213        let unpinned_issues: Vec<_> = result
6214            .dependency_issues
6215            .iter()
6216            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::UnpinnedVersion))
6217            .collect();
6218        assert!(!unpinned_issues.is_empty());
6219
6220        // Should detect deprecated package
6221        let deprecated_issues: Vec<_> = result
6222            .dependency_issues
6223            .iter()
6224            .filter(|issue| matches!(issue.issue_type, DependencyIssueType::DeprecatedPackage))
6225            .collect();
6226        assert!(!deprecated_issues.is_empty());
6227    }
6228
6229    #[test]
6230    fn test_import_analysis() {
6231        let analyzer = PythonAnalyzer::new();
6232        let content = r#"
6233import os
6234import sys
6235import requests
6236import pandas as pd
6237from flask import Flask, render_template
6238from mymodule import function
6239from .relative import local_function
6240from package import *
6241import numpy as np
6242"#;
6243
6244        let result = analyzer.analyze_package_dependencies(content).unwrap();
6245
6246        // Should categorize imports correctly
6247        let stdlib_imports: Vec<_> = result
6248            .import_analysis
6249            .iter()
6250            .filter(|imp| matches!(imp.module_category, ModuleCategory::StandardLibrary))
6251            .collect();
6252        assert!(stdlib_imports.len() >= 2); // os, sys
6253
6254        let third_party_imports: Vec<_> = result
6255            .import_analysis
6256            .iter()
6257            .filter(|imp| matches!(imp.module_category, ModuleCategory::ThirdParty))
6258            .collect();
6259        assert!(third_party_imports.len() >= 3); // requests, pandas, flask, numpy
6260
6261        // Should detect star import issues
6262        let star_import_issues: Vec<_> = result
6263            .import_analysis
6264            .iter()
6265            .filter(|imp| {
6266                imp.import_issues
6267                    .contains(&ImportIssue::StarImportDangerous)
6268            })
6269            .collect();
6270        assert!(!star_import_issues.is_empty());
6271
6272        // Should detect different import types
6273        let from_imports: Vec<_> = result
6274            .import_analysis
6275            .iter()
6276            .filter(|imp| matches!(imp.import_type, ImportType::FromImport))
6277            .collect();
6278        assert!(!from_imports.is_empty());
6279
6280        let alias_imports: Vec<_> = result
6281            .import_analysis
6282            .iter()
6283            .filter(|imp| matches!(imp.import_type, ImportType::AliasImport))
6284            .collect();
6285        assert!(!alias_imports.is_empty());
6286    }
6287
6288    #[test]
6289    fn test_security_vulnerability_scanning() {
6290        let analyzer = PythonAnalyzer::new();
6291        let content = r#"
6292import urllib3
6293import requests
6294import pyyaml
6295
6296urllib3==1.25.8
6297requests==2.19.1
6298pyyaml==5.3.1
6299"#;
6300
6301        let result = analyzer.analyze_package_dependencies(content).unwrap();
6302
6303        // Should detect security vulnerabilities
6304        assert!(!result.security_vulnerabilities.is_empty());
6305
6306        // Should have vulnerabilities for known packages
6307        let urllib3_vulns: Vec<_> = result
6308            .security_vulnerabilities
6309            .iter()
6310            .filter(|vuln| vuln.package_name == "urllib3")
6311            .collect();
6312        assert!(!urllib3_vulns.is_empty());
6313
6314        // Should categorize severity correctly
6315        let critical_vulns: Vec<_> = result
6316            .security_vulnerabilities
6317            .iter()
6318            .filter(|vuln| matches!(vuln.severity, SecurityVulnerabilitySeverity::Critical))
6319            .collect();
6320        assert!(!critical_vulns.is_empty());
6321
6322        // Should have CVE information
6323        let vulns_with_cve: Vec<_> = result
6324            .security_vulnerabilities
6325            .iter()
6326            .filter(|vuln| vuln.cve_id.is_some())
6327            .collect();
6328        assert!(!vulns_with_cve.is_empty());
6329    }
6330
6331    #[test]
6332    fn test_virtual_environment_detection() {
6333        let analyzer = PythonAnalyzer::new();
6334        let content = r#"
6335# Virtual environment indicators
6336python -m venv myenv
6337source myenv/bin/activate
6338pip install -r requirements.txt
6339
6340# Conda environment
6341conda create -n myproject python=3.9
6342conda activate myproject
6343
6344# Pipenv
6345pipenv install requests
6346pipenv shell
6347"#;
6348
6349        let result = analyzer.analyze_package_dependencies(content).unwrap();
6350
6351        // Should detect virtual environments
6352        assert!(!result.virtual_environments.is_empty());
6353
6354        // Should detect different environment types
6355        let venv_envs: Vec<_> = result
6356            .virtual_environments
6357            .iter()
6358            .filter(|env| matches!(env.env_type, VirtualEnvironmentType::Venv))
6359            .collect();
6360        assert!(!venv_envs.is_empty());
6361
6362        let conda_envs: Vec<_> = result
6363            .virtual_environments
6364            .iter()
6365            .filter(|env| matches!(env.env_type, VirtualEnvironmentType::Conda))
6366            .collect();
6367        assert!(!conda_envs.is_empty());
6368
6369        let pipenv_envs: Vec<_> = result
6370            .virtual_environments
6371            .iter()
6372            .filter(|env| matches!(env.env_type, VirtualEnvironmentType::Pipenv))
6373            .collect();
6374        assert!(!pipenv_envs.is_empty());
6375    }
6376
6377    #[test]
6378    fn test_license_analysis() {
6379        let analyzer = PythonAnalyzer::new();
6380        let content = r#"
6381import requests
6382import django
6383import flask
6384
6385requests==2.28.1
6386django==4.1.0
6387flask==2.0.1
6388"#;
6389
6390        let result = analyzer.analyze_package_dependencies(content).unwrap();
6391
6392        // Should analyze licenses
6393        assert!(!result.license_analysis.is_empty());
6394
6395        // Should have license information for dependencies
6396        assert_eq!(result.license_analysis.len(), result.dependencies.len());
6397
6398        // Should assess compatibility
6399        let compatible_licenses: Vec<_> = result
6400            .license_analysis
6401            .iter()
6402            .filter(|license| matches!(license.compatibility, LicenseCompatibility::Compatible))
6403            .collect();
6404        assert!(!compatible_licenses.is_empty());
6405
6406        // Should have license metadata
6407        for license in &result.license_analysis {
6408            assert!(!license.package_name.is_empty());
6409            assert!(matches!(
6410                license.license_type,
6411                LicenseType::MIT
6412                    | LicenseType::Apache2
6413                    | LicenseType::BSD2Clause
6414                    | LicenseType::BSD3Clause
6415                    | LicenseType::Unknown
6416            ));
6417        }
6418    }
6419
6420    #[test]
6421    fn test_modern_features_analysis() {
6422        let analyzer = PythonAnalyzer::new();
6423        let code = r#"
6424            from dataclasses import dataclass
6425            from typing import Optional
6426            import asyncio
6427
6428            @dataclass
6429            class User:
6430                name: str
6431                age: int = 0
6432
6433            async def process_data():
6434                async with asyncio.timeout(10):
6435                    data = [x for x in range(100)]
6436                    processed = (item * 2 for item in data)
6437                    return f"Processed {len(data)} items"
6438
6439            def modern_syntax(value: str | int) -> str:
6440                if (result := calculate(value)) > 10:
6441                    return f"Result: {result:.2f}"
6442                return "Too small"
6443
6444            match value:
6445                case int() if value > 100:
6446                    print("Large number")
6447                case str():
6448                    print("String value")
6449                case _:
6450                    print("Other")
6451        "#;
6452
6453        let analysis = analyzer.analyze_modern_features(code).unwrap();
6454
6455        // Should detect dataclass usage
6456        assert!(!analysis.dataclass_features.is_empty());
6457
6458        // Should detect f-string usage
6459        assert!(!analysis.fstring_features.is_empty());
6460
6461        // Should detect modern syntax (walrus operator, union types)
6462        assert!(!analysis.modern_syntax_features.is_empty());
6463
6464        // Should have a reasonable modernity score
6465        assert!(analysis.overall_modernity_score > 50);
6466        assert!(analysis.overall_modernity_score <= 100);
6467
6468        // Should detect appropriate Python version
6469        assert!(analysis
6470            .python_version_detected
6471            .minimum_version
6472            .starts_with("3."));
6473
6474        // Should provide recommendations
6475        assert!(!analysis.recommendations.is_empty());
6476    }
6477
6478    #[test]
6479    fn test_dataclass_feature_detection() {
6480        let analyzer = PythonAnalyzer::new();
6481        let code = r#"
6482            from dataclasses import dataclass, field
6483            from typing import List
6484
6485            @dataclass(frozen=True)
6486            class ImmutableUser:
6487                name: str
6488                tags: List[str] = field(default_factory=list)
6489                
6490                def __post_init__(self):
6491                    object.__setattr__(self, 'processed', True)
6492
6493            class SlottedClass:
6494                __slots__ = ['x', 'y']
6495                
6496                def __init__(self, x, y):
6497                    self.x = x
6498                    self.y = y
6499        "#;
6500
6501        let analysis = analyzer.analyze_modern_features(code).unwrap();
6502
6503        assert!(!analysis.dataclass_features.is_empty());
6504        let dataclass_info = &analysis.dataclass_features[0];
6505
6506        assert_eq!(
6507            dataclass_info.dataclass_type,
6508            DataclassType::StandardDataclass
6509        );
6510        assert!(dataclass_info
6511            .features_used
6512            .contains(&DataclassFeature::FrozenClass));
6513        assert!(dataclass_info
6514            .features_used
6515            .contains(&DataclassFeature::PostInitProcessing));
6516        assert!(dataclass_info
6517            .features_used
6518            .contains(&DataclassFeature::FieldFactories));
6519        assert!(dataclass_info.best_practices_score > 70);
6520    }
6521
6522    #[test]
6523    fn test_fstring_complexity_analysis() {
6524        let analyzer = PythonAnalyzer::new();
6525        let code = r#"
6526            name = "Alice"
6527            value = 42.5
6528            
6529            # Simple f-string
6530            simple = f"Hello {name}"
6531            
6532            # Complex f-string with formatting
6533            complex = f"Value: {value:.2f}, Length: {len(name)}"
6534            
6535            # Very complex f-string
6536            advanced = f"Result: {calculate_result(value) if value > 0 else 'N/A':.3f}"
6537        "#;
6538
6539        let analysis = analyzer.analyze_modern_features(code).unwrap();
6540
6541        assert!(!analysis.fstring_features.is_empty());
6542        assert!(analysis.fstring_features.len() >= 3);
6543
6544        // Should detect different complexity levels
6545        let complexities: Vec<_> = analysis
6546            .fstring_features
6547            .iter()
6548            .map(|f| &f.complexity)
6549            .collect();
6550
6551        assert!(complexities.contains(&&FStringComplexity::Simple));
6552        assert!(
6553            complexities.contains(&&FStringComplexity::Moderate)
6554                || complexities.contains(&&FStringComplexity::Complex)
6555        );
6556    }
6557
6558    #[test]
6559    fn test_modern_syntax_features() {
6560        let analyzer = PythonAnalyzer::new();
6561        let code = r#"
6562            # Walrus operator (Python 3.8+)
6563            if (length := len(data)) > 10:
6564                print(f"Long data: {length}")
6565
6566            # Union type syntax (Python 3.10+)
6567            def process(value: str | int | None) -> str | None:
6568                return str(value) if value is not None else None
6569
6570            # Positional-only parameters (Python 3.8+)
6571            def func(a, b, /, c, d):
6572                return a + b + c + d
6573
6574            # Modern type hints (Python 3.9+)
6575            data: list[dict[str, int]] = []
6576            mapping: dict[str, set[int]] = {}
6577        "#;
6578
6579        let analysis = analyzer.analyze_modern_features(code).unwrap();
6580
6581        assert!(!analysis.modern_syntax_features.is_empty());
6582
6583        let syntax_types: Vec<_> = analysis
6584            .modern_syntax_features
6585            .iter()
6586            .map(|s| &s.feature_type)
6587            .collect();
6588
6589        assert!(syntax_types.contains(&&ModernSyntaxType::WalrusOperator));
6590        assert!(syntax_types.contains(&&ModernSyntaxType::TypeUnionOperator));
6591        assert!(syntax_types.contains(&&ModernSyntaxType::PositionalOnlyParams));
6592        assert!(syntax_types.contains(&&ModernSyntaxType::GenericTypeHints));
6593
6594        // Should detect Python 3.10+ as minimum version due to union operator
6595        assert!(analysis.python_version_detected.minimum_version >= "3.10".to_string());
6596    }
6597}