using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace MarketAlly.AIPlugin.Analysis.Plugins { [AIPlugin("BehaviorAnalysis", "Analyzes code behavior against specifications and detects semantic drift")] public class BehaviorAnalysisPlugin : IAIPlugin { [AIParameter("Full path to the file or directory to analyze", required: true)] public string Path { get; set; } = string.Empty; [AIParameter("Path to specification file or documentation", required: false)] public string SpecificationPath { get; set; } = string.Empty; [AIParameter("Generate natural language summaries of code behavior", required: false)] public bool GenerateSummaries { get; set; } = true; [AIParameter("Compare behavior against previous versions", required: false)] public bool CompareVersions { get; set; } = false; [AIParameter("Detect breaking changes in public APIs", required: false)] public bool DetectBreakingChanges { get; set; } = true; [AIParameter("Validate intent alignment with specifications", required: false)] public bool ValidateIntent { get; set; } = true; [AIParameter("Generate behavior test suggestions", required: false)] public bool SuggestTests { get; set; } = true; public IReadOnlyDictionary SupportedParameters => new Dictionary { ["path"] = typeof(string), ["specificationPath"] = typeof(string), ["generateSummaries"] = typeof(bool), ["compareVersions"] = typeof(bool), ["detectBreakingChanges"] = typeof(bool), ["validateIntent"] = typeof(bool), ["suggestTests"] = typeof(bool) }; public async Task ExecuteAsync(IReadOnlyDictionary parameters) { try { // Extract parameters string path = parameters["path"]?.ToString() ?? string.Empty; string? specificationPath = parameters.TryGetValue("specificationPath", out var specPath) ? specPath?.ToString() : null; bool generateSummaries = GetBoolParameter(parameters, "generateSummaries", true); bool compareVersions = GetBoolParameter(parameters, "compareVersions", false); bool detectBreakingChanges = GetBoolParameter(parameters, "detectBreakingChanges", true); bool validateIntent = GetBoolParameter(parameters, "validateIntent", true); bool suggestTests = GetBoolParameter(parameters, "suggestTests", true); // Validate path if (!File.Exists(path) && !Directory.Exists(path)) { return new AIPluginResult( new FileNotFoundException($"Path not found: {path}"), "Path not found" ); } // Initialize behavior analysis var analysis = new BehaviorAnalysis { AnalysisPath = path, SpecificationPath = specificationPath ?? string.Empty, AnalysisDate = DateTime.UtcNow, BehaviorSummaries = new List(), SpecificationAlignments = new List(), SemanticDrifts = new List(), BreakingChanges = new List(), TestSuggestions = new List(), IntentValidations = new List() }; // Discover and analyze code files await DiscoverAndAnalyzeCode(path, analysis); // Load and analyze specifications if (!string.IsNullOrEmpty(specificationPath) && File.Exists(specificationPath)) { await AnalyzeSpecifications(specificationPath, analysis); } // Generate behavior summaries if (generateSummaries) { await GenerateBehaviorSummaries(analysis); } // Compare with previous versions if (compareVersions) { await CompareWithPreviousVersions(analysis); } // Detect breaking changes if (detectBreakingChanges) { await DetectBreakingChangesMethod(analysis); } // Validate intent alignment if (validateIntent) { await ValidateIntentAlignment(analysis); } // Generate test suggestions if (suggestTests) { await GenerateBehaviorTestSuggestions(analysis); } // Calculate behavior health score var behaviorScore = CalculateBehaviorScore(analysis); var result = new { Path = path, SpecificationPath = specificationPath, AnalysisDate = analysis.AnalysisDate, BehaviorScore = behaviorScore, CodeStructure = new { TotalClasses = analysis.AnalyzedClasses.Count, TotalMethods = analysis.AnalyzedMethods.Count, PublicAPIs = analysis.AnalyzedMethods.Count(m => m.IsPublic), BusinessLogicMethods = analysis.AnalyzedMethods.Count(m => m.HasBusinessLogic) }, BehaviorSummary = generateSummaries && analysis.BehaviorSummaries.Any() ? analysis.BehaviorSummaries.First().Summary : "Behavior summary generation was disabled or no summaries generated", SpecificationAlignment = validateIntent && !string.IsNullOrEmpty(specificationPath) ? analysis.SpecificationAlignments.Select(s => new { s.Component, s.SpecificationRequirement, s.ActualBehavior, s.AlignmentLevel, s.Discrepancies, s.Recommendations }).ToList() : null, SemanticDrift = compareVersions ? analysis.SemanticDrifts.Select(d => new { d.Component, d.DriftType, d.Description, d.Severity, d.Impact, d.Recommendation, d.DetectedAt }).ToList() : null, BreakingChanges = detectBreakingChanges ? analysis.BreakingChanges.Select(b => new { b.ChangeType, b.Component, b.Description, b.Impact, b.Severity, b.MitigationStrategy, b.AffectedAPIs }).ToList() : null, TestSuggestions = suggestTests ? analysis.TestSuggestions.Select(t => new { t.TestType, t.TargetComponent, t.BehaviorToTest, t.TestScenario, t.Priority, t.Rationale, t.Implementation }).OrderByDescending(t => t.Priority).ToList() : null, IntentValidation = validateIntent ? new { OverallAlignment = analysis.IntentValidations.Any() ? analysis.IntentValidations.Average(i => i.AlignmentScore) : 0, ValidatedComponents = analysis.IntentValidations.Count, HighAlignmentComponents = analysis.IntentValidations.Count(i => i.AlignmentScore >= 80), LowAlignmentComponents = analysis.IntentValidations.Count(i => i.AlignmentScore < 60), KeyFindings = analysis.IntentValidations .Where(i => i.AlignmentScore < 70) .Select(i => $"{i.Component}: {i.Finding}") .Take(5) .ToList() } : null, Summary = new { OverallBehaviorHealth = GetBehaviorHealth(behaviorScore), CriticalIssues = analysis.BreakingChanges.Count(b => b.Severity == "High") + analysis.SemanticDrifts.Count(d => d.Severity == "High"), SpecificationCompliance = analysis.SpecificationAlignments.Any() ? $"{analysis.SpecificationAlignments.Count(s => s.AlignmentLevel >= 80)}/{analysis.SpecificationAlignments.Count} components aligned" : "No specifications provided", TopRecommendations = GetTopBehaviorRecommendations(analysis), BehaviorComplexity = GetBehaviorComplexity(analysis) } }; return new AIPluginResult(result, $"Behavior analysis completed. Score: {behaviorScore}/100. " + $"Analyzed {analysis.AnalyzedMethods.Count} methods across {analysis.AnalyzedClasses.Count} classes."); } catch (Exception ex) { return new AIPluginResult(ex, "Failed to analyze code behavior"); } } private Task DetectBreakingChangesMethod(BehaviorAnalysis analysis) { foreach (var method in analysis.AnalyzedMethods.Where(m => m.IsPublic)) { var breakingChanges = AnalyzeMethodForBreakingChanges(method); analysis.BreakingChanges.AddRange(breakingChanges); } foreach (var classInfo in analysis.AnalyzedClasses.Where(c => c.IsPublic)) { var breakingChanges = AnalyzeClassForBreakingChanges(classInfo); analysis.BreakingChanges.AddRange(breakingChanges); } return Task.CompletedTask; } private async Task DiscoverAndAnalyzeCode(string path, BehaviorAnalysis analysis) { var files = GetFilesToAnalyze(path); foreach (var filePath in files) { var sourceCode = await File.ReadAllTextAsync(filePath); var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode, path: filePath); var root = await syntaxTree.GetRootAsync(); // Analyze classes var classes = root.DescendantNodes().OfType(); foreach (var cls in classes) { var classInfo = AnalyzeClassBehavior(cls, filePath); analysis.AnalyzedClasses.Add(classInfo); } // Analyze methods var methods = root.DescendantNodes().OfType(); foreach (var method in methods) { var methodInfo = AnalyzeMethodBehavior(method, filePath); analysis.AnalyzedMethods.Add(methodInfo); } } } private ClassBehaviorInfo AnalyzeClassBehavior(ClassDeclarationSyntax cls, string filePath) { var className = cls.Identifier.ValueText; var namespaceName = GetNamespace(cls); return new ClassBehaviorInfo { Name = className, FullName = $"{namespaceName}.{className}", Namespace = namespaceName, FilePath = filePath, IsPublic = cls.Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword)), IsAbstract = cls.Modifiers.Any(m => m.IsKind(SyntaxKind.AbstractKeyword)), BaseTypes = cls.BaseList?.Types.Select(t => t.Type.ToString()).ToList() ?? new List(), Responsibilities = ExtractClassResponsibilities(cls), DesignPatterns = DetectDesignPatterns(cls), BehaviorCategory = DetermineBehaviorCategory(cls), ComplexityIndicators = AnalyzeClassComplexity(cls) }; } private MethodBehaviorInfo AnalyzeMethodBehavior(MethodDeclarationSyntax method, string filePath) { var className = GetContainingClassName(method); var methodName = method.Identifier.ValueText; return new MethodBehaviorInfo { Name = methodName, ClassName = className, FilePath = filePath, LineNumber = method.GetLocation().GetLineSpan().StartLinePosition.Line + 1, IsPublic = method.Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword)), IsAsync = method.Modifiers.Any(m => m.IsKind(SyntaxKind.AsyncKeyword)), ReturnType = method.ReturnType.ToString(), Parameters = ExtractParameterInfo(method), BehaviorType = DetermineBehaviorType(method), SideEffects = AnalyzeSideEffects(method), Preconditions = ExtractPreconditions(method), Postconditions = ExtractPostconditions(method), BusinessRules = ExtractBusinessRules(method), HasBusinessLogic = HasBusinessLogic(method), DataFlow = AnalyzeDataFlow(method), ControlFlow = AnalyzeControlFlow(method) }; } private async Task AnalyzeSpecifications(string specificationPath, BehaviorAnalysis analysis) { var specContent = await File.ReadAllTextAsync(specificationPath); var requirements = ParseSpecificationRequirements(specContent); analysis.SpecificationRequirements = requirements; } private Task GenerateBehaviorSummaries(BehaviorAnalysis analysis) { // Generate overall system behavior summary var systemSummary = new BehaviorSummary { Component = "System", BehaviorType = "Overall", Summary = GenerateSystemBehaviorSummary(analysis), KeyBehaviors = ExtractKeySystemBehaviors(analysis), ComplexityLevel = GetComplexityLevel(CalculateSystemComplexity(analysis)), BusinessValue = AssessBusinessValue(analysis) }; analysis.BehaviorSummaries.Add(systemSummary); // Generate class-level summaries for key classes var keyClasses = analysis.AnalyzedClasses .Where(c => c.IsPublic || c.BehaviorCategory == "BusinessLogic") .Take(10); foreach (var classInfo in keyClasses) { var classSummary = new BehaviorSummary { Component = classInfo.Name, BehaviorType = "Class", Summary = GenerateClassBehaviorSummary(classInfo, analysis), KeyBehaviors = ExtractClassKeyBehaviors(classInfo, analysis), ComplexityLevel = GetComplexityLevel(classInfo.ComplexityIndicators.GetValueOrDefault("CyclomaticComplexity", 0)), BusinessValue = AssessClassBusinessValue(classInfo) }; analysis.BehaviorSummaries.Add(classSummary); } return Task.CompletedTask; } private async Task CompareWithPreviousVersions(BehaviorAnalysis analysis) { // Load previous analysis if available var previousAnalysisPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(analysis.AnalysisPath) ?? string.Empty, ".behavior-history.json"); if (File.Exists(previousAnalysisPath)) { try { var previousData = await File.ReadAllTextAsync(previousAnalysisPath); var previousAnalysis = JsonSerializer.Deserialize(previousData); if (previousAnalysis != null) { DetectSemanticDrift(analysis, previousAnalysis); } } catch { // Ignore errors loading previous analysis } } // Save current analysis for future comparison await SaveBehaviorSnapshot(analysis, previousAnalysisPath); } private Task ValidateIntentAlignment(BehaviorAnalysis analysis) { foreach (var method in analysis.AnalyzedMethods) { var validation = ValidateMethodIntent(method, analysis.SpecificationRequirements); analysis.IntentValidations.Add(validation); } foreach (var classInfo in analysis.AnalyzedClasses) { var validation = ValidateClassIntent(classInfo, analysis.SpecificationRequirements); analysis.IntentValidations.Add(validation); } return Task.CompletedTask; } private Task GenerateBehaviorTestSuggestions(BehaviorAnalysis analysis) { foreach (var method in analysis.AnalyzedMethods) { var suggestions = GenerateMethodTestSuggestions(method); analysis.TestSuggestions.AddRange(suggestions); } // Generate integration test suggestions var integrationSuggestions = GenerateIntegrationTestSuggestions(analysis); analysis.TestSuggestions.AddRange(integrationSuggestions); // Generate behavior-driven test suggestions var bddSuggestions = GenerateBDDTestSuggestions(analysis); analysis.TestSuggestions.AddRange(bddSuggestions); return Task.CompletedTask; } // Helper methods for behavior analysis private List GetFilesToAnalyze(string path) { var files = new List(); if (File.Exists(path) && path.EndsWith(".cs")) { files.Add(path); } else if (Directory.Exists(path)) { files.AddRange(Directory.GetFiles(path, "*.cs", SearchOption.AllDirectories) .Where(f => !f.Contains("\\bin\\") && !f.Contains("\\obj\\") && !f.EndsWith(".Designer.cs") && !f.EndsWith(".g.cs"))); } return files; } private string GetNamespace(SyntaxNode node) { var namespaceDecl = node.Ancestors().OfType().FirstOrDefault(); return namespaceDecl?.Name.ToString() ?? "Global"; } private string GetContainingClassName(SyntaxNode node) { var classDeclaration = node.Ancestors().OfType().FirstOrDefault(); return classDeclaration?.Identifier.ValueText ?? "Unknown"; } private List ExtractClassResponsibilities(ClassDeclarationSyntax cls) { var responsibilities = new List(); // Analyze method names to infer responsibilities var methods = cls.DescendantNodes().OfType(); var methodGroups = methods .GroupBy(m => GetMethodCategory(m.Identifier.ValueText)) .Where(g => g.Key != "Unknown"); foreach (var group in methodGroups) { responsibilities.Add($"{group.Key} operations ({group.Count()} methods)"); } // Analyze properties for data responsibilities var properties = cls.DescendantNodes().OfType(); if (properties.Any()) { responsibilities.Add($"Data management ({properties.Count()} properties)"); } return responsibilities; } private List DetectDesignPatterns(ClassDeclarationSyntax cls) { var patterns = new List(); var className = cls.Identifier.ValueText; // Pattern detection based on naming and structure if (className.EndsWith("Factory")) patterns.Add("Factory Pattern"); if (className.EndsWith("Builder")) patterns.Add("Builder Pattern"); if (className.EndsWith("Observer")) patterns.Add("Observer Pattern"); if (className.EndsWith("Strategy")) patterns.Add("Strategy Pattern"); if (className.EndsWith("Command")) patterns.Add("Command Pattern"); if (className.EndsWith("Facade")) patterns.Add("Facade Pattern"); if (className.EndsWith("Adapter")) patterns.Add("Adapter Pattern"); if (className.EndsWith("Repository")) patterns.Add("Repository Pattern"); if (className.EndsWith("Service")) patterns.Add("Service Pattern"); // Singleton pattern detection var constructors = cls.DescendantNodes().OfType(); if (constructors.Any(c => c.Modifiers.Any(m => m.IsKind(SyntaxKind.PrivateKeyword)))) { var fields = cls.DescendantNodes().OfType(); if (fields.Any(f => f.Modifiers.Any(m => m.IsKind(SyntaxKind.StaticKeyword)))) { patterns.Add("Singleton Pattern"); } } return patterns; } private string DetermineBehaviorCategory(ClassDeclarationSyntax cls) { var className = cls.Identifier.ValueText.ToLowerInvariant(); var methods = cls.DescendantNodes().OfType(); if (className.Contains("controller")) return "Presentation"; if (className.Contains("service")) return "BusinessLogic"; if (className.Contains("repository") || className.Contains("dao")) return "DataAccess"; if (className.Contains("model") || className.Contains("entity")) return "Domain"; if (className.Contains("dto") || className.Contains("request") || className.Contains("response")) return "DataTransfer"; if (className.Contains("helper") || className.Contains("util")) return "Utility"; // Analyze method patterns var businessMethods = methods.Count(m => HasBusinessLogic(m)); var dataMethods = methods.Count(m => AccessesData(m)); if (businessMethods > methods.Count() * 0.6) return "BusinessLogic"; if (dataMethods > methods.Count() * 0.5) return "DataAccess"; return "General"; } private Dictionary AnalyzeClassComplexity(ClassDeclarationSyntax cls) { var metrics = new Dictionary(); var methods = cls.DescendantNodes().OfType(); var properties = cls.DescendantNodes().OfType(); metrics["MethodCount"] = methods.Count(); metrics["PropertyCount"] = properties.Count(); metrics["CyclomaticComplexity"] = methods.Sum(m => CalculateMethodComplexity(m)); metrics["Responsibilities"] = ExtractClassResponsibilities(cls).Count; metrics["Dependencies"] = ExtractClassDependencies(cls).Count; return metrics; } private List ExtractParameterInfo(MethodDeclarationSyntax method) { return method.ParameterList.Parameters.Select(p => new ParameterInfo { Name = p.Identifier.ValueText, Type = p.Type?.ToString() ?? "unknown", HasDefaultValue = p.Default != null, IsOptional = p.Modifiers.Any(m => m.IsKind(SyntaxKind.ParamsKeyword)) }).ToList(); } private string DetermineBehaviorType(MethodDeclarationSyntax method) { var methodName = method.Identifier.ValueText.ToLowerInvariant(); var returnType = method.ReturnType.ToString().ToLowerInvariant(); if (methodName.StartsWith("get") || methodName.StartsWith("retrieve")) return "Query"; if (methodName.StartsWith("set") || methodName.StartsWith("update") || methodName.StartsWith("save")) return "Command"; if (methodName.StartsWith("create") || methodName.StartsWith("add")) return "Creation"; if (methodName.StartsWith("delete") || methodName.StartsWith("remove")) return "Deletion"; if (methodName.StartsWith("validate") || methodName.StartsWith("check")) return "Validation"; if (methodName.StartsWith("calculate") || methodName.StartsWith("compute")) return "Computation"; if (methodName.StartsWith("process") || methodName.StartsWith("handle")) return "Processing"; if (returnType == "bool" || methodName.StartsWith("is") || methodName.StartsWith("has")) return "Predicate"; return "General"; } private List AnalyzeSideEffects(MethodDeclarationSyntax method) { var sideEffects = new List(); var methodBody = method.Body?.ToString() ?? method.ExpressionBody?.ToString() ?? ""; if (methodBody.Contains("Console.Write") || methodBody.Contains("Console.Out")) sideEffects.Add("Console Output"); if (methodBody.Contains("File.") || methodBody.Contains("Directory.")) sideEffects.Add("File System Access"); if (methodBody.Contains("HttpClient") || methodBody.Contains("WebRequest")) sideEffects.Add("Network Communication"); if (methodBody.Contains("Database") || methodBody.Contains("Connection") || methodBody.Contains("Command")) sideEffects.Add("Database Modification"); // Check for field modifications var assignments = method.DescendantNodes().OfType(); if (assignments.Any(a => !IsLocalVariable(a.Left))) sideEffects.Add("State Modification"); if (method.Modifiers.Any(m => m.IsKind(SyntaxKind.AsyncKeyword))) sideEffects.Add("Asynchronous Operation"); return sideEffects; } private List ExtractPreconditions(MethodDeclarationSyntax method) { var preconditions = new List(); // Look for parameter validation var throwStatements = method.DescendantNodes().OfType(); foreach (var throwStmt in throwStatements) { var condition = ExtractConditionFromThrow(throwStmt); if (!string.IsNullOrEmpty(condition)) { preconditions.Add(condition); } } // Look for guard clauses var ifStatements = method.DescendantNodes().OfType().Take(3); // First few conditions are likely guards foreach (var ifStmt in ifStatements) { if (IsGuardClause(ifStmt)) { preconditions.Add($"Guard: {ifStmt.Condition}"); } } return preconditions; } private List ExtractPostconditions(MethodDeclarationSyntax method) { var postconditions = new List(); var returnType = method.ReturnType.ToString(); // Analyze return statements var returnStatements = method.DescendantNodes().OfType(); if (returnStatements.Any() && returnType != "void") { postconditions.Add($"Returns: {returnType}"); } // Look for assertions or validation at method end var lastStatements = GetLastStatements(method, 3); foreach (var stmt in lastStatements) { if (IsPostconditionCheck(stmt)) { postconditions.Add($"Ensures: {stmt}"); } } return postconditions; } private List ExtractBusinessRules(MethodDeclarationSyntax method) { var businessRules = new List(); // Look for business logic patterns var ifStatements = method.DescendantNodes().OfType(); foreach (var ifStmt in ifStatements) { if (IsBusinessRule(ifStmt)) { businessRules.Add($"Rule: {SimplifyCondition(ifStmt.Condition.ToString())}"); } } // Look for switch statements (often business rules) var switchStatements = method.DescendantNodes().OfType(); foreach (var switchStmt in switchStatements) { businessRules.Add($"Business Logic Switch: {switchStmt.Expression}"); } return businessRules; } private bool HasBusinessLogic(MethodDeclarationSyntax method) { var methodName = method.Identifier.ValueText.ToLowerInvariant(); var businessKeywords = new[] { "calculate", "process", "validate", "execute", "handle", "manage", "apply", "determine" }; if (businessKeywords.Any(keyword => methodName.Contains(keyword))) return true; // Check for complex logic var complexity = CalculateMethodComplexity(method); return complexity > 5; } private List AnalyzeDataFlow(MethodDeclarationSyntax method) { var dataFlow = new List(); var parameters = method.ParameterList.Parameters; var returnType = method.ReturnType.ToString(); if (parameters.Any()) { dataFlow.Add($"Input: {string.Join(", ", parameters.Select(p => p.Type))}"); } if (returnType != "void") { dataFlow.Add($"Output: {returnType}"); } // Analyze intermediate data transformations var variableDeclarations = method.DescendantNodes().OfType(); var transformations = variableDeclarations.Count(); if (transformations > 0) { dataFlow.Add($"Transformations: {transformations} intermediate variables"); } return dataFlow; } private List AnalyzeControlFlow(MethodDeclarationSyntax method) { var controlFlow = new List(); var ifStatements = method.DescendantNodes().OfType().Count(); var loops = method.DescendantNodes().OfType().Count() + method.DescendantNodes().OfType().Count() + method.DescendantNodes().OfType().Count(); var switches = method.DescendantNodes().OfType().Count(); var tryCatch = method.DescendantNodes().OfType().Count(); if (ifStatements > 0) controlFlow.Add($"Conditional: {ifStatements} if statements"); if (loops > 0) controlFlow.Add($"Iterative: {loops} loops"); if (switches > 0) controlFlow.Add($"Selection: {switches} switch statements"); if (tryCatch > 0) controlFlow.Add($"Exception Handling: {tryCatch} try-catch blocks"); var complexity = CalculateMethodComplexity(method); controlFlow.Add($"Cyclomatic Complexity: {complexity}"); return controlFlow; } private List ParseSpecificationRequirements(string specContent) { var requirements = new List(); // Simple parsing for common specification formats var lines = specContent.Split('\n', StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var trimmedLine = line.Trim(); // Look for requirement patterns if (trimmedLine.StartsWith("REQ-") || trimmedLine.StartsWith("REQUIREMENT") || trimmedLine.Contains("SHALL") || trimmedLine.Contains("MUST")) { requirements.Add(new SpecificationRequirement { Id = ExtractRequirementId(trimmedLine), Description = trimmedLine, Priority = DetermineRequirementPriority(trimmedLine), Category = DetermineRequirementCategory(trimmedLine) }); } } return requirements; } private string GenerateSystemBehaviorSummary(BehaviorAnalysis analysis) { var summary = new List(); summary.Add($"System contains {analysis.AnalyzedClasses.Count} classes and {analysis.AnalyzedMethods.Count} methods."); var publicMethods = analysis.AnalyzedMethods.Count(m => m.IsPublic); summary.Add($"Exposes {publicMethods} public methods as API surface."); var behaviorCategories = analysis.AnalyzedClasses .GroupBy(c => c.BehaviorCategory) .ToDictionary(g => g.Key, g => g.Count()); summary.Add("Behavior distribution:"); foreach (var category in behaviorCategories) { summary.Add($" - {category.Key}: {category.Value} classes"); } var businessLogicMethods = analysis.AnalyzedMethods.Count(m => m.HasBusinessLogic); summary.Add($"Contains {businessLogicMethods} methods with business logic."); return string.Join(" ", summary); } private List ExtractKeySystemBehaviors(BehaviorAnalysis analysis) { var keyBehaviors = new List(); // Extract most common behavior types var behaviorTypes = analysis.AnalyzedMethods .GroupBy(m => m.BehaviorType) .OrderByDescending(g => g.Count()) .Take(5); foreach (var behavior in behaviorTypes) { keyBehaviors.Add($"{behavior.Key} operations ({behavior.Count()} methods)"); } // Extract key side effects var sideEffects = analysis.AnalyzedMethods .SelectMany(m => m.SideEffects) .GroupBy(s => s) .OrderByDescending(g => g.Count()) .Take(3); foreach (var effect in sideEffects) { keyBehaviors.Add($"{effect.Key} ({effect.Count()} occurrences)"); } return keyBehaviors; } private int CalculateSystemComplexity(BehaviorAnalysis analysis) { var totalComplexity = analysis.AnalyzedClasses.Sum(c => c.ComplexityIndicators.GetValueOrDefault("CyclomaticComplexity", 0)); var averageComplexity = analysis.AnalyzedClasses.Count > 0 ? totalComplexity / analysis.AnalyzedClasses.Count : 0; return averageComplexity; } private string AssessBusinessValue(BehaviorAnalysis analysis) { var businessLogicRatio = analysis.AnalyzedMethods.Count > 0 ? (double)analysis.AnalyzedMethods.Count(m => m.HasBusinessLogic) / analysis.AnalyzedMethods.Count : 0; if (businessLogicRatio > 0.6) return "High"; if (businessLogicRatio > 0.3) return "Medium"; return "Low"; } private string GenerateClassBehaviorSummary(ClassBehaviorInfo classInfo, BehaviorAnalysis analysis) { var summary = new List(); summary.Add($"{classInfo.Name} is a {classInfo.BehaviorCategory} class"); if (classInfo.Responsibilities.Any()) { summary.Add($"with responsibilities: {string.Join(", ", classInfo.Responsibilities)}"); } if (classInfo.DesignPatterns.Any()) { summary.Add($"Implements: {string.Join(", ", classInfo.DesignPatterns)}"); } var methodCount = analysis.AnalyzedMethods.Count(m => m.ClassName == classInfo.Name); summary.Add($"Contains {methodCount} methods"); return string.Join(". ", summary); } private List ExtractClassKeyBehaviors(ClassBehaviorInfo classInfo, BehaviorAnalysis analysis) { var keyBehaviors = new List(); var classMethods = analysis.AnalyzedMethods.Where(m => m.ClassName == classInfo.Name); // Group methods by behavior type var behaviorGroups = classMethods .GroupBy(m => m.BehaviorType) .OrderByDescending(g => g.Count()); foreach (var group in behaviorGroups.Take(3)) { keyBehaviors.Add($"{group.Key} ({group.Count()} methods)"); } // Add significant side effects var sideEffects = classMethods .SelectMany(m => m.SideEffects) .GroupBy(s => s) .OrderByDescending(g => g.Count()) .Take(2); foreach (var effect in sideEffects) { keyBehaviors.Add($"{effect.Key}"); } return keyBehaviors; } private void DetectSemanticDrift(BehaviorAnalysis current, BehaviorSnapshot previous) { // Compare method signatures and behaviors foreach (var currentMethod in current.AnalyzedMethods) { var previousMethod = previous.Methods.FirstOrDefault(m => m.Name == currentMethod.Name && m.ClassName == currentMethod.ClassName); if (previousMethod != null) { var drifts = CompareMethodBehavior(currentMethod, previousMethod); current.SemanticDrifts.AddRange(drifts); } } // Compare class structures foreach (var currentClass in current.AnalyzedClasses) { var previousClass = previous.Classes.FirstOrDefault(c => c.Name == currentClass.Name); if (previousClass != null) { var drifts = CompareClassBehavior(currentClass, previousClass); current.SemanticDrifts.AddRange(drifts); } } } private List CompareMethodBehavior(MethodBehaviorInfo current, MethodSnapshot previous) { var drifts = new List(); // Check behavior type changes if (current.BehaviorType != previous.BehaviorType) { drifts.Add(new SemanticDrift { Component = $"{current.ClassName}.{current.Name}", DriftType = "Behavior Type Change", Description = $"Behavior changed from {previous.BehaviorType} to {current.BehaviorType}", Severity = "Medium", Impact = "Method semantics may have changed", Recommendation = "Review method implementation and update documentation", DetectedAt = DateTime.UtcNow }); } // Check side effects changes var newSideEffects = current.SideEffects.Except(previous.SideEffects).ToList(); var removedSideEffects = previous.SideEffects.Except(current.SideEffects).ToList(); if (newSideEffects.Any()) { drifts.Add(new SemanticDrift { Component = $"{current.ClassName}.{current.Name}", DriftType = "New Side Effects", Description = $"Added side effects: {string.Join(", ", newSideEffects)}", Severity = "High", Impact = "Method now has additional side effects", Recommendation = "Ensure callers handle new side effects appropriately", DetectedAt = DateTime.UtcNow }); } if (removedSideEffects.Any()) { drifts.Add(new SemanticDrift { Component = $"{current.ClassName}.{current.Name}", DriftType = "Removed Side Effects", Description = $"Removed side effects: {string.Join(", ", removedSideEffects)}", Severity = "Medium", Impact = "Method no longer produces certain side effects", Recommendation = "Verify that removed side effects are not needed", DetectedAt = DateTime.UtcNow }); } return drifts; } private List CompareClassBehavior(ClassBehaviorInfo current, ClassSnapshot previous) { var drifts = new List(); // Check responsibility changes var newResponsibilities = current.Responsibilities.Except(previous.Responsibilities).ToList(); var removedResponsibilities = previous.Responsibilities.Except(current.Responsibilities).ToList(); if (newResponsibilities.Any()) { drifts.Add(new SemanticDrift { Component = current.Name, DriftType = "New Responsibilities", Description = $"Added responsibilities: {string.Join(", ", newResponsibilities)}", Severity = "Medium", Impact = "Class scope has expanded", Recommendation = "Consider if class is becoming too complex", DetectedAt = DateTime.UtcNow }); } return drifts; } private async Task SaveBehaviorSnapshot(BehaviorAnalysis analysis, string snapshotPath) { var snapshot = new BehaviorSnapshot { AnalysisDate = analysis.AnalysisDate, Classes = analysis.AnalyzedClasses.Select(c => new ClassSnapshot { Name = c.Name, BehaviorCategory = c.BehaviorCategory, Responsibilities = c.Responsibilities, DesignPatterns = c.DesignPatterns }).ToList(), Methods = analysis.AnalyzedMethods.Select(m => new MethodSnapshot { Name = m.Name, ClassName = m.ClassName, BehaviorType = m.BehaviorType, SideEffects = m.SideEffects, HasBusinessLogic = m.HasBusinessLogic }).ToList() }; try { var json = JsonSerializer.Serialize(snapshot, new JsonSerializerOptions { WriteIndented = true }); await File.WriteAllTextAsync(snapshotPath, json); } catch { // Ignore save errors } } private List AnalyzeMethodForBreakingChanges(MethodBehaviorInfo method) { var breakingChanges = new List(); // Check for potential breaking changes based on method characteristics if (method.SideEffects.Contains("Database Modification")) { breakingChanges.Add(new BreakingChange { ChangeType = "Data Modification", Component = $"{method.ClassName}.{method.Name}", Description = "Method modifies database state", Impact = "Callers may experience data consistency issues", Severity = "Medium", MitigationStrategy = "Ensure proper transaction handling and rollback capabilities", AffectedAPIs = new List { $"{method.ClassName}.{method.Name}" } }); } if (method.SideEffects.Contains("Network Communication")) { breakingChanges.Add(new BreakingChange { ChangeType = "External Dependency", Component = $"{method.ClassName}.{method.Name}", Description = "Method depends on external network services", Impact = "Method may fail due to network issues", Severity = "Low", MitigationStrategy = "Implement retry logic and graceful degradation", AffectedAPIs = new List { $"{method.ClassName}.{method.Name}" } }); } return breakingChanges; } private List AnalyzeClassForBreakingChanges(ClassBehaviorInfo classInfo) { var breakingChanges = new List(); // Check for inheritance changes if (classInfo.BaseTypes.Any()) { breakingChanges.Add(new BreakingChange { ChangeType = "Inheritance Structure", Component = classInfo.Name, Description = "Class has inheritance relationships that may constrain changes", Impact = "Changes may affect derived classes", Severity = "Medium", MitigationStrategy = "Use interface segregation and dependency inversion", AffectedAPIs = new List { classInfo.Name } }); } return breakingChanges; } private IntentValidation ValidateMethodIntent(MethodBehaviorInfo method, List requirements) { var validation = new IntentValidation { Component = $"{method.ClassName}.{method.Name}", ComponentType = "Method", ExpectedIntent = DetermineExpectedIntent(method), ActualBehavior = DescribeActualBehavior(method), AlignmentScore = CalculateAlignmentScore(method, requirements), Finding = GenerateAlignmentFinding(method, requirements), Recommendations = GenerateAlignmentRecommendations(method, requirements) }; return validation; } private IntentValidation ValidateClassIntent(ClassBehaviorInfo classInfo, List requirements) { var validation = new IntentValidation { Component = classInfo.Name, ComponentType = "Class", ExpectedIntent = $"Implement {classInfo.BehaviorCategory} functionality", ActualBehavior = string.Join(", ", classInfo.Responsibilities), AlignmentScore = CalculateClassAlignmentScore(classInfo, requirements), Finding = GenerateClassAlignmentFinding(classInfo, requirements), Recommendations = GenerateClassAlignmentRecommendations(classInfo) }; return validation; } private List GenerateMethodTestSuggestions(MethodBehaviorInfo method) { var suggestions = new List(); // Basic behavior tests suggestions.Add(new BehaviorTestSuggestion { TestType = "Behavior Verification", TargetComponent = $"{method.ClassName}.{method.Name}", BehaviorToTest = $"Method exhibits {method.BehaviorType} behavior correctly", TestScenario = $"Given valid inputs, when {method.Name} is called, then it should perform {method.BehaviorType} operation", Priority = method.IsPublic ? 8 : 5, Rationale = $"Verify core {method.BehaviorType} behavior", Implementation = GenerateTestImplementation(method) }); // Side effect tests foreach (var sideEffect in method.SideEffects) { suggestions.Add(new BehaviorTestSuggestion { TestType = "Side Effect Verification", TargetComponent = $"{method.ClassName}.{method.Name}", BehaviorToTest = $"Method produces {sideEffect} side effect correctly", TestScenario = $"When {method.Name} is called, then {sideEffect} should occur as expected", Priority = GetSideEffectTestPriority(sideEffect), Rationale = $"Ensure {sideEffect} side effect is properly controlled", Implementation = GenerateSideEffectTestImplementation(method, sideEffect) }); } // Business rule tests foreach (var rule in method.BusinessRules) { suggestions.Add(new BehaviorTestSuggestion { TestType = "Business Rule Verification", TargetComponent = $"{method.ClassName}.{method.Name}", BehaviorToTest = $"Business rule implementation: {rule}", TestScenario = $"Given business scenario, when rule applies, then {rule} should be enforced", Priority = 9, Rationale = "Business rules are critical for domain correctness", Implementation = GenerateBusinessRuleTestImplementation(method, rule) }); } return suggestions; } private List GenerateIntegrationTestSuggestions(BehaviorAnalysis analysis) { var suggestions = new List(); // Find classes that interact with external systems var externallyConnectedClasses = analysis.AnalyzedClasses .Where(c => analysis.AnalyzedMethods .Where(m => m.ClassName == c.Name) .Any(m => m.SideEffects.Contains("Database Modification") || m.SideEffects.Contains("Network Communication"))) .ToList(); foreach (var cls in externallyConnectedClasses) { suggestions.Add(new BehaviorTestSuggestion { TestType = "Integration Test", TargetComponent = cls.Name, BehaviorToTest = "End-to-end integration with external systems", TestScenario = $"Given real external dependencies, when {cls.Name} operations are performed, then integration should work correctly", Priority = 7, Rationale = "Verify integration points work correctly in realistic scenarios", Implementation = $"Create integration tests with test containers or mock services for {cls.Name}" }); } return suggestions; } private List GenerateBDDTestSuggestions(BehaviorAnalysis analysis) { var suggestions = new List(); var businessLogicClasses = analysis.AnalyzedClasses .Where(c => c.BehaviorCategory == "BusinessLogic") .ToList(); foreach (var cls in businessLogicClasses) { suggestions.Add(new BehaviorTestSuggestion { TestType = "Behavior-Driven Test", TargetComponent = cls.Name, BehaviorToTest = "Business behavior from user perspective", TestScenario = $"Given business context, when user performs action, then {cls.Name} should deliver expected business outcome", Priority = 8, Rationale = "Ensure business behavior matches stakeholder expectations", Implementation = $"Create Gherkin scenarios for {cls.Name} business operations" }); } return suggestions; } // Utility and helper methods private int CalculateMethodComplexity(MethodDeclarationSyntax method) { var complexity = 1; var descendants = method.DescendantNodes(); complexity += descendants.OfType().Count(); complexity += descendants.OfType().Count(); complexity += descendants.OfType().Count(); complexity += descendants.OfType().Count(); complexity += descendants.OfType().Count(); complexity += descendants.OfType().Count(); return complexity; } private string GetMethodCategory(string methodName) { var name = methodName.ToLowerInvariant(); if (name.StartsWith("get") || name.StartsWith("retrieve") || name.StartsWith("find")) return "Data Retrieval"; if (name.StartsWith("set") || name.StartsWith("update") || name.StartsWith("save")) return "Data Modification"; if (name.StartsWith("create") || name.StartsWith("add") || name.StartsWith("insert")) return "Data Creation"; if (name.StartsWith("delete") || name.StartsWith("remove")) return "Data Deletion"; if (name.StartsWith("validate") || name.StartsWith("check") || name.StartsWith("verify")) return "Validation"; if (name.StartsWith("calculate") || name.StartsWith("compute")) return "Calculation"; if (name.StartsWith("process") || name.StartsWith("handle") || name.StartsWith("execute")) return "Processing"; return "Unknown"; } private bool AccessesData(MethodDeclarationSyntax method) { var methodBody = method.Body?.ToString() ?? method.ExpressionBody?.ToString() ?? ""; var dataKeywords = new[] { "database", "repository", "entity", "dbcontext", "connection", "command", "query" }; return dataKeywords.Any(keyword => methodBody.ToLowerInvariant().Contains(keyword)); } private List ExtractClassDependencies(ClassDeclarationSyntax cls) { var dependencies = new HashSet(); // Extract from field types var fields = cls.DescendantNodes().OfType(); foreach (var field in fields) { dependencies.Add(field.Declaration.Type.ToString()); } // Extract from property types var properties = cls.DescendantNodes().OfType(); foreach (var property in properties) { dependencies.Add(property.Type.ToString()); } // Extract from constructor parameters var constructors = cls.DescendantNodes().OfType(); foreach (var constructor in constructors) { foreach (var param in constructor.ParameterList.Parameters) { dependencies.Add(param.Type?.ToString() ?? "unknown"); } } return dependencies.Where(d => !string.IsNullOrEmpty(d) && !d.StartsWith("System.")).ToList(); } private bool IsLocalVariable(ExpressionSyntax expression) { // Simple heuristic to determine if assignment target is a local variable return expression is IdentifierNameSyntax identifier && char.IsLower(identifier.Identifier.ValueText[0]); } private string ExtractConditionFromThrow(ThrowStatementSyntax throwStmt) { var expression = throwStmt.Expression?.ToString() ?? ""; if (expression.Contains("ArgumentNullException")) return "Parameter must not be null"; if (expression.Contains("ArgumentException")) return "Parameter must be valid"; if (expression.Contains("InvalidOperationException")) return "Object must be in valid state"; return "Precondition check"; } private bool IsGuardClause(IfStatementSyntax ifStmt) { // Check if if statement is likely a guard clause (early return/throw) var statement = ifStmt.Statement; return statement is ThrowStatementSyntax || (statement is BlockSyntax block && block.Statements.Count == 1 && (block.Statements[0] is ThrowStatementSyntax || block.Statements[0] is ReturnStatementSyntax)); } private List GetLastStatements(MethodDeclarationSyntax method, int count) { var statements = method.Body?.Statements ?? new SyntaxList(); return statements.TakeLast(count).ToList(); } private bool IsPostconditionCheck(StatementSyntax statement) { var statementText = statement.ToString().ToLowerInvariant(); return statementText.Contains("assert") || statementText.Contains("ensure") || statementText.Contains("contract"); } private bool IsBusinessRule(IfStatementSyntax ifStmt) { var condition = ifStmt.Condition.ToString().ToLowerInvariant(); var businessIndicators = new[] { "status", "state", "type", "category", "amount", "count", "limit", "threshold" }; return businessIndicators.Any(indicator => condition.Contains(indicator)); } private string SimplifyCondition(string condition) { // Simplify complex conditions for readability if (condition.Length > 50) { return condition.Substring(0, 47) + "..."; } return condition; } private string GetComplexityLevel(int complexity) { return complexity switch { <= 5 => "Low", <= 10 => "Medium", <= 20 => "High", _ => "Very High" }; } private string AssessClassBusinessValue(ClassBehaviorInfo classInfo) { if (classInfo.BehaviorCategory == "BusinessLogic") return "High"; if (classInfo.BehaviorCategory == "Domain") return "High"; if (classInfo.BehaviorCategory == "Presentation") return "Medium"; if (classInfo.BehaviorCategory == "DataAccess") return "Medium"; return "Low"; } private string ExtractRequirementId(string requirementText) { var match = Regex.Match(requirementText, @"REQ-\d+"); return match.Success ? match.Value : $"REQ-{Guid.NewGuid().ToString("N")[..8]}"; } private string DetermineRequirementPriority(string requirementText) { var text = requirementText.ToLowerInvariant(); if (text.Contains("critical") || text.Contains("must")) return "High"; if (text.Contains("should") || text.Contains("important")) return "Medium"; return "Low"; } private string DetermineRequirementCategory(string requirementText) { var text = requirementText.ToLowerInvariant(); if (text.Contains("performance") || text.Contains("speed")) return "Performance"; if (text.Contains("security") || text.Contains("authentication")) return "Security"; if (text.Contains("usability") || text.Contains("user")) return "Usability"; if (text.Contains("functional") || text.Contains("business")) return "Functional"; return "General"; } private string DetermineExpectedIntent(MethodBehaviorInfo method) { return $"Perform {method.BehaviorType} operation with appropriate {string.Join(", ", method.SideEffects)} handling"; } private string DescribeActualBehavior(MethodBehaviorInfo method) { var behaviors = new List { $"{method.BehaviorType} operation" }; if (method.SideEffects.Any()) behaviors.Add($"Side effects: {string.Join(", ", method.SideEffects)}"); if (method.BusinessRules.Any()) behaviors.Add($"Business rules: {method.BusinessRules.Count}"); return string.Join("; ", behaviors); } private int CalculateAlignmentScore(MethodBehaviorInfo method, List requirements) { // Simple scoring based on method characteristics var score = 70; // Base score if (method.HasBusinessLogic) score += 10; if (method.Preconditions.Any()) score += 5; if (method.Postconditions.Any()) score += 5; if (method.BusinessRules.Any()) score += 10; // Penalty for excessive side effects if (method.SideEffects.Count > 3) score -= 10; return Math.Max(0, Math.Min(100, score)); } private string GenerateAlignmentFinding(MethodBehaviorInfo method, List requirements) { if (method.HasBusinessLogic && method.BusinessRules.Any()) { return "Method implements business logic with defined rules"; } if (method.SideEffects.Count > 2) { return "Method has multiple side effects that may need review"; } if (!method.Preconditions.Any() && method.Parameters.Any()) { return "Method lacks input validation"; } return "Method behavior appears aligned with expected patterns"; } private List GenerateAlignmentRecommendations(MethodBehaviorInfo method, List requirements) { var recommendations = new List(); if (!method.Preconditions.Any() && method.Parameters.Any()) { recommendations.Add("Add input validation and precondition checks"); } if (method.SideEffects.Count > 2) { recommendations.Add("Consider breaking method into smaller, more focused operations"); } if (!method.BusinessRules.Any() && method.HasBusinessLogic) { recommendations.Add("Document business rules and make them more explicit"); } return recommendations; } private int CalculateClassAlignmentScore(ClassBehaviorInfo classInfo, List requirements) { var score = 70; // Base score if (classInfo.DesignPatterns.Any()) score += 15; if (classInfo.Responsibilities.Count <= 3) score += 10; // Single Responsibility if (classInfo.ComplexityIndicators["CyclomaticComplexity"] < 50) score += 5; return Math.Max(0, Math.Min(100, score)); } private string GenerateClassAlignmentFinding(ClassBehaviorInfo classInfo, List requirements) { if (classInfo.Responsibilities.Count > 5) { return "Class has many responsibilities and may violate Single Responsibility Principle"; } if (classInfo.DesignPatterns.Any()) { return $"Class implements recognized design patterns: {string.Join(", ", classInfo.DesignPatterns)}"; } return "Class structure follows standard patterns"; } private List GenerateClassAlignmentRecommendations(ClassBehaviorInfo classInfo) { var recommendations = new List(); if (classInfo.Responsibilities.Count > 5) { recommendations.Add("Consider splitting class to improve cohesion"); } if (!classInfo.DesignPatterns.Any() && classInfo.ComplexityIndicators["MethodCount"] > 10) { recommendations.Add("Consider applying design patterns to improve structure"); } return recommendations; } private string GenerateTestImplementation(MethodBehaviorInfo method) { return $"Create unit test for {method.Name} that verifies {method.BehaviorType} behavior with various input scenarios"; } private int GetSideEffectTestPriority(string sideEffect) { return sideEffect switch { "Database Modification" => 9, "Network Communication" => 8, "File System Access" => 7, "State Modification" => 6, _ => 5 }; } private string GenerateSideEffectTestImplementation(MethodBehaviorInfo method, string sideEffect) { return $"Create test that verifies {sideEffect} occurs correctly when {method.Name} is called"; } private string GenerateBusinessRuleTestImplementation(MethodBehaviorInfo method, string rule) { return $"Create test scenarios that validate business rule: {rule}"; } private int CalculateBehaviorScore(BehaviorAnalysis analysis) { var score = 100; // Deduct for complexity issues var avgComplexity = CalculateSystemComplexity(analysis); if (avgComplexity > 20) score -= 20; else if (avgComplexity > 10) score -= 10; // Deduct for breaking changes var criticalBreakingChanges = analysis.BreakingChanges.Count(b => b.Severity == "High"); score -= criticalBreakingChanges * 15; // Deduct for semantic drift var criticalDrifts = analysis.SemanticDrifts.Count(d => d.Severity == "High"); score -= criticalDrifts * 10; // Bonus for good alignment var avgAlignment = analysis.IntentValidations.Any() ? analysis.IntentValidations.Average(i => i.AlignmentScore) : 70; if (avgAlignment > 80) score += 10; return Math.Max(0, Math.Min(100, score)); } private string GetBehaviorHealth(int score) { return score switch { >= 80 => "Excellent", >= 60 => "Good", >= 40 => "Fair", >= 20 => "Poor", _ => "Critical" }; } private string GetBehaviorComplexity(BehaviorAnalysis analysis) { var avgComplexity = CalculateSystemComplexity(analysis); return avgComplexity switch { <= 5 => "Low", <= 10 => "Moderate", <= 20 => "High", _ => "Very High" }; } private List GetTopBehaviorRecommendations(BehaviorAnalysis analysis) { var recommendations = new List(); var criticalBreaking = analysis.BreakingChanges.Count(b => b.Severity == "High"); if (criticalBreaking > 0) { recommendations.Add($"Address {criticalBreaking} critical breaking changes"); } var criticalDrifts = analysis.SemanticDrifts.Count(d => d.Severity == "High"); if (criticalDrifts > 0) { recommendations.Add($"Review {criticalDrifts} critical semantic drifts"); } var lowAlignmentComponents = analysis.IntentValidations.Count(i => i.AlignmentScore < 60); if (lowAlignmentComponents > 0) { recommendations.Add($"Improve alignment for {lowAlignmentComponents} components"); } var highComplexityClasses = analysis.AnalyzedClasses.Count(c => c.ComplexityIndicators.GetValueOrDefault("CyclomaticComplexity", 0) > 20); if (highComplexityClasses > 0) { recommendations.Add($"Refactor {highComplexityClasses} high-complexity classes"); } var highPriorityTests = analysis.TestSuggestions.Count(t => t.Priority >= 8); if (highPriorityTests > 0) { recommendations.Add($"Implement {highPriorityTests} high-priority behavior tests"); } if (!recommendations.Any()) { recommendations.Add("Behavior analysis shows good alignment - continue maintaining standards"); } return recommendations.Take(5).ToList(); } private bool GetBoolParameter(IReadOnlyDictionary parameters, string key, bool defaultValue) { return parameters.TryGetValue(key, out var value) ? Convert.ToBoolean(value) : defaultValue; } } // Supporting data structures for behavior analysis public class BehaviorAnalysis { public string AnalysisPath { get; set; } = string.Empty; public string? SpecificationPath { get; set; } public DateTime AnalysisDate { get; set; } public List AnalyzedClasses { get; set; } = new(); public List AnalyzedMethods { get; set; } = new(); public List SpecificationRequirements { get; set; } = new(); public List BehaviorSummaries { get; set; } = new(); public List SpecificationAlignments { get; set; } = new(); public List SemanticDrifts { get; set; } = new(); public List BreakingChanges { get; set; } = new(); public List TestSuggestions { get; set; } = new(); public List IntentValidations { get; set; } = new(); } public class ClassBehaviorInfo { public string Name { get; set; } = string.Empty; public string FullName { get; set; } = string.Empty; public string Namespace { get; set; } = string.Empty; public string FilePath { get; set; } = string.Empty; public bool IsPublic { get; set; } public bool IsAbstract { get; set; } public List BaseTypes { get; set; } = new(); public List Responsibilities { get; set; } = new(); public List DesignPatterns { get; set; } = new(); public string BehaviorCategory { get; set; } = string.Empty; public Dictionary ComplexityIndicators { get; set; } = new(); } public class MethodBehaviorInfo { public string Name { get; set; } = string.Empty; public string ClassName { get; set; } = string.Empty; public string FilePath { get; set; } = string.Empty; public int LineNumber { get; set; } public bool IsPublic { get; set; } public bool IsAsync { get; set; } public string ReturnType { get; set; } = string.Empty; public List Parameters { get; set; } = new(); public string BehaviorType { get; set; } = string.Empty; public List SideEffects { get; set; } = new(); public List Preconditions { get; set; } = new(); public List Postconditions { get; set; } = new(); public List BusinessRules { get; set; } = new(); public bool HasBusinessLogic { get; set; } public List DataFlow { get; set; } = new(); public List ControlFlow { get; set; } = new(); } public class ParameterInfo { public string Name { get; set; } = string.Empty; public string Type { get; set; } = string.Empty; public bool HasDefaultValue { get; set; } public bool IsOptional { get; set; } } public class SpecificationRequirement { public string Id { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string Priority { get; set; } = string.Empty; public string Category { get; set; } = string.Empty; } public class BehaviorSummary { public string Component { get; set; } = string.Empty; public string BehaviorType { get; set; } = string.Empty; public string Summary { get; set; } = string.Empty; public List KeyBehaviors { get; set; } = new(); public string ComplexityLevel { get; set; } = string.Empty; public string BusinessValue { get; set; } = string.Empty; } public class SpecificationAlignment { public string Component { get; set; } = string.Empty; public string SpecificationRequirement { get; set; } = string.Empty; public string ActualBehavior { get; set; } = string.Empty; public int AlignmentLevel { get; set; } public List Discrepancies { get; set; } = new(); public List Recommendations { get; set; } = new(); } public class SemanticDrift { public string Component { get; set; } = string.Empty; public string DriftType { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string Severity { get; set; } = string.Empty; public string Impact { get; set; } = string.Empty; public string Recommendation { get; set; } = string.Empty; public DateTime DetectedAt { get; set; } } public class BreakingChange { public string ChangeType { get; set; } = string.Empty; public string Component { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string Impact { get; set; } = string.Empty; public string Severity { get; set; } = string.Empty; public string MitigationStrategy { get; set; } = string.Empty; public List AffectedAPIs { get; set; } = new(); } public class BehaviorTestSuggestion { public string TestType { get; set; } = string.Empty; public string TargetComponent { get; set; } = string.Empty; public string BehaviorToTest { get; set; } = string.Empty; public string TestScenario { get; set; } = string.Empty; public int Priority { get; set; } public string Rationale { get; set; } = string.Empty; public string Implementation { get; set; } = string.Empty; } public class IntentValidation { public string Component { get; set; } = string.Empty; public string ComponentType { get; set; } = string.Empty; public string ExpectedIntent { get; set; } = string.Empty; public string ActualBehavior { get; set; } = string.Empty; public int AlignmentScore { get; set; } public string Finding { get; set; } = string.Empty; public List Recommendations { get; set; } = new(); } public class BehaviorSnapshot { public DateTime AnalysisDate { get; set; } public List Classes { get; set; } = new(); public List Methods { get; set; } = new(); } public class ClassSnapshot { public string Name { get; set; } = string.Empty; public string BehaviorCategory { get; set; } = string.Empty; public List Responsibilities { get; set; } = new(); public List DesignPatterns { get; set; } = new(); } public class MethodSnapshot { public string Name { get; set; } = string.Empty; public string ClassName { get; set; } = string.Empty; public string BehaviorType { get; set; } = string.Empty; public List SideEffects { get; set; } = new(); public bool HasBusinessLogic { get; set; } } }