using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using System.Text.Json; using Microsoft.Extensions.Logging; using MarketAlly.AIPlugin; using MarketAlly.AIPlugin.Analysis.Plugins; namespace MarketAlly.AIPlugin.Analysis.TestConsole { class Program { private static readonly ILoggerFactory _loggerFactory = LoggerFactory.Create(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Information)); private static readonly ILogger _logger = _loggerFactory.CreateLogger(); static async Task Main(string[] args) { Console.WriteLine("🚀 MarketAlly AI Plugin Analysis Test Console"); Console.WriteLine("=============================================="); try { // Initialize plugin registry with correct logger type var registryLogger = _loggerFactory.CreateLogger(); var registry = new AIPluginRegistry(registryLogger); // Register all Analysis plugins RegisterAnalysisPlugins(registry); // Show menu options await ShowMainMenu(registry); } catch (Exception ex) { Console.WriteLine($"❌ Error during analysis: {ex.Message}"); _logger.LogError(ex, "Analysis failed"); } finally { _loggerFactory?.Dispose(); } Console.WriteLine(); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } private static async Task ShowMainMenu(AIPluginRegistry registry) { while (true) { Console.WriteLine(); Console.WriteLine("📋 Analysis Options:"); Console.WriteLine("1. 📁 Analyze C# Project (Full Analysis Suite)"); Console.WriteLine("2. 🗄️ Analyze SQLite Database Schema"); Console.WriteLine("3. 🔍 Run Individual Analysis Plugin"); Console.WriteLine("4. 📊 Generate Sample Database for Testing"); Console.WriteLine("0. ❌ Exit"); Console.WriteLine(); Console.Write("Select an option (0-4): "); var choice = Console.ReadLine(); switch (choice) { case "1": await RunProjectAnalysis(registry); break; case "2": await RunDatabaseAnalysis(registry); break; case "3": await RunIndividualAnalysis(registry); break; case "4": await GenerateSampleDatabase(); break; case "0": return; default: Console.WriteLine("❌ Invalid option. Please try again."); break; } } } private static async Task RunProjectAnalysis(AIPluginRegistry registry) { var testProjectPath = GetTestProjectPath(); if (string.IsNullOrEmpty(testProjectPath)) { Console.WriteLine("❌ No test project path provided. Please specify a C# project directory."); return; } Console.WriteLine($"📁 Analyzing project: {testProjectPath}"); Console.WriteLine(); // Run all analysis plugins await RunComplexityAnalysis(registry, testProjectPath); await RunPerformanceAnalysis(registry, testProjectPath); await RunTechnicalDebtAnalysis(registry, testProjectPath); await RunArchitectureValidation(registry, testProjectPath); await RunTestAnalysis(registry, testProjectPath); await RunBehaviorAnalysis(registry, testProjectPath); // Generate comprehensive report await GenerateComprehensiveReport(registry, testProjectPath); Console.WriteLine(); Console.WriteLine("✅ Analysis complete! Check the generated reports for detailed results."); } private static async Task RunDatabaseAnalysis(AIPluginRegistry registry) { Console.WriteLine(); Console.WriteLine("🗄️ SQLite Database Schema Analysis"); Console.WriteLine("====================================="); var databasePath = GetDatabasePath(); if (string.IsNullOrEmpty(databasePath)) { return; } // Show database analysis options Console.WriteLine(); Console.WriteLine("📋 Database Analysis Options:"); Console.WriteLine("1. 📖 Basic Schema (Structure only)"); Console.WriteLine("2. 📊 Detailed Analysis (with row counts and indexes)"); Console.WriteLine("3. 🔍 Comprehensive Analysis (everything + sample data)"); Console.WriteLine("4. 📝 Human-readable Report"); Console.WriteLine("5. 📄 JSON Export"); Console.WriteLine(); Console.Write("Select analysis type (1-5): "); var choice = Console.ReadLine(); switch (choice) { case "1": await RunBasicSchemaAnalysis(registry, databasePath); break; case "2": await RunDetailedSchemaAnalysis(registry, databasePath); break; case "3": await RunComprehensiveSchemaAnalysis(registry, databasePath); break; case "4": await RunReadableSchemaAnalysis(registry, databasePath); break; case "5": await RunJsonSchemaAnalysis(registry, databasePath); break; default: Console.WriteLine("❌ Invalid option. Running basic analysis..."); await RunBasicSchemaAnalysis(registry, databasePath); break; } } private static string GetDatabasePath() { // Check for sample database first var sampleDbPath = "sample-database.db"; if (File.Exists(sampleDbPath)) { Console.WriteLine($"🎯 Found sample database: {sampleDbPath}"); Console.Write("Use sample database? (y/n): "); var useSample = Console.ReadLine()?.ToLower(); if (useSample == "y" || useSample == "yes" || string.IsNullOrEmpty(useSample)) { return sampleDbPath; } } // Look for .db files in current directory var dbFiles = Directory.GetFiles(".", "*.db"); if (dbFiles.Length > 0) { Console.WriteLine("📂 Found SQLite database files:"); for (int i = 0; i < dbFiles.Length; i++) { Console.WriteLine($" {i + 1}. {Path.GetFileName(dbFiles[i])}"); } Console.Write($"Select a database file (1-{dbFiles.Length}) or enter custom path: "); var selection = Console.ReadLine(); if (int.TryParse(selection, out int index) && index >= 1 && index <= dbFiles.Length) { return dbFiles[index - 1]; } // If not a number, treat as custom path if (!string.IsNullOrEmpty(selection) && File.Exists(selection)) { return selection; } } // Prompt for custom path Console.Write("Enter the path to a SQLite database file (.db): "); var userPath = Console.ReadLine(); if (!string.IsNullOrEmpty(userPath) && File.Exists(userPath)) { return userPath; } Console.WriteLine("❌ Database file not found or invalid path."); return null; } private static async Task RunBasicSchemaAnalysis(AIPluginRegistry registry, string databasePath) { Console.WriteLine("🔍 Running Basic Schema Analysis..."); var parameters = new Dictionary { ["databasePath"] = databasePath, ["includeRowCounts"] = false, ["includeIndexes"] = false, ["includeForeignKeys"] = false, ["includeMetadata"] = false, ["outputFormat"] = "structured" }; await ExecuteDatabaseAnalysis(registry, parameters, "basic-schema"); } private static async Task RunDetailedSchemaAnalysis(AIPluginRegistry registry, string databasePath) { Console.WriteLine("📊 Running Detailed Schema Analysis..."); var parameters = new Dictionary { ["databasePath"] = databasePath, ["includeRowCounts"] = true, ["includeIndexes"] = true, ["includeForeignKeys"] = true, ["includeMetadata"] = true, ["outputFormat"] = "structured" }; await ExecuteDatabaseAnalysis(registry, parameters, "detailed-schema"); } private static async Task RunComprehensiveSchemaAnalysis(AIPluginRegistry registry, string databasePath) { Console.WriteLine("🔍 Running Comprehensive Schema Analysis..."); var parameters = new Dictionary { ["databasePath"] = databasePath, ["includeRowCounts"] = true, ["includeIndexes"] = true, ["includeForeignKeys"] = true, ["includeMetadata"] = true, ["outputFormat"] = "structured", ["maxSampleRows"] = 3 }; await ExecuteDatabaseAnalysis(registry, parameters, "comprehensive-schema"); } private static async Task RunReadableSchemaAnalysis(AIPluginRegistry registry, string databasePath) { Console.WriteLine("📝 Running Human-Readable Schema Analysis..."); var parameters = new Dictionary { ["databasePath"] = databasePath, ["includeRowCounts"] = true, ["includeIndexes"] = true, ["includeForeignKeys"] = true, ["includeMetadata"] = true, ["outputFormat"] = "readable" }; await ExecuteDatabaseAnalysis(registry, parameters, "readable-schema"); } private static async Task RunJsonSchemaAnalysis(AIPluginRegistry registry, string databasePath) { Console.WriteLine("📄 Running JSON Schema Export..."); var parameters = new Dictionary { ["databasePath"] = databasePath, ["includeRowCounts"] = true, ["includeIndexes"] = true, ["includeForeignKeys"] = true, ["includeMetadata"] = true, ["outputFormat"] = "json" }; await ExecuteDatabaseAnalysis(registry, parameters, "json-schema"); } private static async Task ExecuteDatabaseAnalysis(AIPluginRegistry registry, Dictionary parameters, string outputPrefix) { try { var result = await registry.CallFunctionAsync("SQLiteSchemaReader", parameters); if (result.Success) { Console.WriteLine(" ✅ Database schema analysis completed"); var outputFormat = parameters["outputFormat"].ToString(); var dbName = Path.GetFileNameWithoutExtension(parameters["databasePath"].ToString()); if (outputFormat == "readable") { // For readable format, save as .txt and display preview var filename = $"{outputPrefix}-{dbName}.txt"; await File.WriteAllTextAsync(filename, result.Data.ToString()); Console.WriteLine($" 📄 Human-readable report saved to: {filename}"); // Show preview Console.WriteLine(); Console.WriteLine("📋 Schema Preview:"); Console.WriteLine(new string('=', 50)); var lines = result.Data.ToString().Split('\n'); for (int i = 0; i < Math.Min(20, lines.Length); i++) { Console.WriteLine(lines[i]); } if (lines.Length > 20) { Console.WriteLine($"... ({lines.Length - 20} more lines in full report)"); } } else { // For structured/json formats, save as JSON var filename = $"{outputPrefix}-{dbName}.json"; await SaveResultToFile(filename, result.Data); PrintDatabaseSummary(result.Data); } } else { Console.WriteLine($" ❌ Database analysis failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($" ❌ Database analysis error: {ex.Message}"); } } private static void PrintDatabaseSummary(object data) { try { var jsonElement = JsonSerializer.Deserialize(JsonSerializer.Serialize(data)); Console.WriteLine(" 📊 Database Summary:"); if (jsonElement.TryGetProperty("databaseName", out var name)) { Console.WriteLine($" Database: {name.GetString()}"); } if (jsonElement.TryGetProperty("tableCount", out var tableCount)) { Console.WriteLine($" Tables: {tableCount.GetInt32()}"); } if (jsonElement.TryGetProperty("tables", out var tables) && tables.ValueKind == JsonValueKind.Array) { Console.WriteLine(" Table Details:"); foreach (var table in tables.EnumerateArray()) { if (table.TryGetProperty("name", out var tableName)) { var name_str = tableName.GetString(); var details = new List(); if (table.TryGetProperty("columns", out var columns) && columns.ValueKind == JsonValueKind.Array) { details.Add($"{columns.GetArrayLength()} columns"); } if (table.TryGetProperty("rowCount", out var rowCount)) { details.Add($"{rowCount.GetInt64():N0} rows"); } if (table.TryGetProperty("indexes", out var indexes) && indexes.ValueKind == JsonValueKind.Array) { var indexCount = indexes.GetArrayLength(); if (indexCount > 0) { details.Add($"{indexCount} indexes"); } } if (table.TryGetProperty("foreignKeys", out var fks) && fks.ValueKind == JsonValueKind.Array) { var fkCount = fks.GetArrayLength(); if (fkCount > 0) { details.Add($"{fkCount} FKs"); } } Console.WriteLine($" • {name_str} ({string.Join(", ", details)})"); } } } if (jsonElement.TryGetProperty("metadata", out var metadata)) { if (metadata.TryGetProperty("formattedSize", out var size)) { Console.WriteLine($" Size: {size.GetString()}"); } if (metadata.TryGetProperty("sqliteVersion", out var version)) { Console.WriteLine($" SQLite Version: {version.GetString()}"); } } } catch (Exception ex) { Console.WriteLine($" ⚠️ Could not parse database summary: {ex.Message}"); } } private static async Task RunIndividualAnalysis(AIPluginRegistry registry) { Console.WriteLine(); Console.WriteLine("🔍 Individual Analysis Plugins"); Console.WriteLine("==============================="); Console.WriteLine("1. ComplexityAnalyzer"); Console.WriteLine("2. PerformanceAnalyzer"); Console.WriteLine("3. TechnicalDebt"); Console.WriteLine("4. ArchitectureValidator"); Console.WriteLine("5. TestAnalysis"); Console.WriteLine("6. BehaviorAnalysis"); Console.WriteLine("7. SQLiteSchemaReader"); Console.WriteLine(); Console.Write("Select plugin to run (1-7): "); var choice = Console.ReadLine(); switch (choice) { case "1": var projectPath = GetTestProjectPath(); if (!string.IsNullOrEmpty(projectPath)) await RunComplexityAnalysis(registry, projectPath); break; case "2": projectPath = GetTestProjectPath(); if (!string.IsNullOrEmpty(projectPath)) await RunPerformanceAnalysis(registry, projectPath); break; case "3": projectPath = GetTestProjectPath(); if (!string.IsNullOrEmpty(projectPath)) await RunTechnicalDebtAnalysis(registry, projectPath); break; case "4": projectPath = GetTestProjectPath(); if (!string.IsNullOrEmpty(projectPath)) await RunArchitectureValidation(registry, projectPath); break; case "5": projectPath = GetTestProjectPath(); if (!string.IsNullOrEmpty(projectPath)) await RunTestAnalysis(registry, projectPath); break; case "6": projectPath = GetTestProjectPath(); if (!string.IsNullOrEmpty(projectPath)) await RunBehaviorAnalysis(registry, projectPath); break; case "7": await RunDatabaseAnalysis(registry); break; default: Console.WriteLine("❌ Invalid option."); break; } } private static async Task GenerateSampleDatabase() { Console.WriteLine("📊 Generating Sample SQLite Database..."); try { var dbPath = "sample-database.db"; // Delete existing sample database if it exists if (File.Exists(dbPath)) { File.Delete(dbPath); } var connectionString = $"Data Source={dbPath}"; using var connection = new Microsoft.Data.Sqlite.SqliteConnection(connectionString); await connection.OpenAsync(); // Create sample tables with various schema features var createScript = @" -- Users table with primary key and constraints CREATE TABLE Users ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Username TEXT NOT NULL UNIQUE, Email TEXT NOT NULL, CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP, IsActive BOOLEAN DEFAULT 1, ProfileData TEXT ); -- Posts table with foreign key relationship CREATE TABLE Posts ( Id INTEGER PRIMARY KEY AUTOINCREMENT, UserId INTEGER NOT NULL, Title TEXT NOT NULL, Content TEXT, PublishedAt DATETIME, ViewCount INTEGER DEFAULT 0, FOREIGN KEY (UserId) REFERENCES Users(Id) ON DELETE CASCADE ); -- Comments table with multiple foreign keys CREATE TABLE Comments ( Id INTEGER PRIMARY KEY AUTOINCREMENT, PostId INTEGER NOT NULL, UserId INTEGER NOT NULL, ParentCommentId INTEGER, Content TEXT NOT NULL, CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (PostId) REFERENCES Posts(Id) ON DELETE CASCADE, FOREIGN KEY (UserId) REFERENCES Users(Id) ON DELETE CASCADE, FOREIGN KEY (ParentCommentId) REFERENCES Comments(Id) ON DELETE CASCADE ); -- Tags table for many-to-many relationship example CREATE TABLE Tags ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL UNIQUE, Description TEXT, Color TEXT DEFAULT '#000000' ); -- Junction table for posts and tags CREATE TABLE PostTags ( PostId INTEGER NOT NULL, TagId INTEGER NOT NULL, PRIMARY KEY (PostId, TagId), FOREIGN KEY (PostId) REFERENCES Posts(Id) ON DELETE CASCADE, FOREIGN KEY (TagId) REFERENCES Tags(Id) ON DELETE CASCADE ); -- Create indexes for performance CREATE INDEX idx_posts_userid ON Posts(UserId); CREATE INDEX idx_posts_published ON Posts(PublishedAt); CREATE INDEX idx_comments_postid ON Comments(PostId); CREATE INDEX idx_comments_userid ON Comments(UserId); CREATE UNIQUE INDEX idx_users_email ON Users(Email); CREATE INDEX idx_tags_name ON Tags(Name); -- Insert sample data INSERT INTO Users (Username, Email, IsActive) VALUES ('john_doe', 'john@example.com', 1), ('jane_smith', 'jane@example.com', 1), ('bob_wilson', 'bob@example.com', 0), ('alice_brown', 'alice@example.com', 1), ('charlie_davis', 'charlie@example.com', 1); INSERT INTO Tags (Name, Description, Color) VALUES ('Technology', 'Posts about technology and programming', '#007acc'), ('Science', 'Scientific discoveries and research', '#00cc7a'), ('Entertainment', 'Movies, music, and entertainment', '#cc7a00'), ('Sports', 'Sports news and updates', '#cc0000'), ('Travel', 'Travel guides and experiences', '#7a00cc'); INSERT INTO Posts (UserId, Title, Content, PublishedAt, ViewCount) VALUES (1, 'Introduction to SQLite', 'SQLite is a lightweight database engine...', '2024-01-15 10:00:00', 150), (1, 'Database Design Best Practices', 'When designing a database schema...', '2024-01-20 14:30:00', 89), (2, 'Machine Learning Basics', 'Understanding the fundamentals of ML...', '2024-01-25 09:15:00', 234), (4, 'Travel Tips for Europe', 'Here are some great tips for European travel...', '2024-02-01 16:45:00', 67), (5, 'Football Season Preview', 'Looking ahead to the upcoming season...', '2024-02-05 11:20:00', 45); INSERT INTO PostTags (PostId, TagId) VALUES (1, 1), -- Introduction to SQLite -> Technology (2, 1), -- Database Design -> Technology (3, 1), -- Machine Learning -> Technology (3, 2), -- Machine Learning -> Science (4, 5), -- Travel Tips -> Travel (5, 4); -- Football Preview -> Sports INSERT INTO Comments (PostId, UserId, Content, CreatedAt) VALUES (1, 2, 'Great introduction! Very helpful for beginners.', '2024-01-15 12:30:00'), (1, 4, 'I agree, SQLite is perfect for small applications.', '2024-01-15 15:45:00'), (2, 3, 'Could you cover indexing strategies next?', '2024-01-21 09:00:00'), (3, 1, 'Nice overview of ML concepts.', '2024-01-26 08:30:00'), (3, 5, 'What tools do you recommend for beginners?', '2024-01-26 10:15:00'), (4, 2, 'I used these tips on my recent trip - very useful!', '2024-02-02 14:20:00'); "; using var command = connection.CreateCommand(); command.CommandText = createScript; await command.ExecuteNonQueryAsync(); Console.WriteLine($" ✅ Sample database created: {dbPath}"); Console.WriteLine(" 📊 Database contains:"); Console.WriteLine(" • 5 tables (Users, Posts, Comments, Tags, PostTags)"); Console.WriteLine(" • Foreign key relationships"); Console.WriteLine(" • Various indexes"); Console.WriteLine(" • Sample data for testing"); Console.WriteLine(); Console.WriteLine(" 🎯 You can now use this database for schema analysis testing!"); } catch (Exception ex) { Console.WriteLine($" ❌ Failed to generate sample database: {ex.Message}"); } } private static void RegisterAnalysisPlugins(AIPluginRegistry registry) { Console.WriteLine("🔧 Registering Analysis plugins..."); try { registry.RegisterPlugin(new ComplexityAnalyzerPlugin()); Console.WriteLine(" ✓ ComplexityAnalyzerPlugin registered"); registry.RegisterPlugin(new PerformanceAnalyzerPlugin()); Console.WriteLine(" ✓ PerformanceAnalyzerPlugin registered"); registry.RegisterPlugin(new TechnicalDebtPlugin()); Console.WriteLine(" ✓ TechnicalDebtPlugin registered"); registry.RegisterPlugin(new ArchitectureValidatorPlugin()); Console.WriteLine(" ✓ ArchitectureValidatorPlugin registered"); registry.RegisterPlugin(new TestAnalysisPlugin()); Console.WriteLine(" ✓ TestAnalysisPlugin registered"); registry.RegisterPlugin(new BehaviorAnalysisPlugin()); Console.WriteLine(" ✓ BehaviorAnalysisPlugin registered"); // Register the new SQLite Schema Reader plugin var sqliteLogger = _loggerFactory.CreateLogger(); registry.RegisterPlugin(new SQLiteSchemaReaderPlugin(sqliteLogger)); Console.WriteLine(" ✓ SQLiteSchemaReaderPlugin registered"); Console.WriteLine($"📊 Total plugins registered: {registry.GetAllPluginSchemas().Count}"); } catch (Exception ex) { Console.WriteLine($"❌ Failed to register plugins: {ex.Message}"); throw; } Console.WriteLine(); } private static string GetTestProjectPath() { var args = Environment.GetCommandLineArgs(); // Check command line arguments if (args.Length > 1 && Directory.Exists(args[1])) { return args[1]; } // Try current directory var currentDir = Directory.GetCurrentDirectory(); if (HasCSharpFiles(currentDir)) { return currentDir; } // Try common project locations var testPaths = new[] { Path.Combine(currentDir, "TestProject"), Path.Combine(currentDir, "src"), Path.Combine(currentDir, "Source"), Path.Combine(Directory.GetParent(currentDir)?.FullName ?? "", "TestProject") }; foreach (var testPath in testPaths) { if (Directory.Exists(testPath) && HasCSharpFiles(testPath)) { return testPath; } } // Prompt user for path Console.Write("Enter the path to a C# project directory: "); var userPath = Console.ReadLine(); if (!string.IsNullOrEmpty(userPath) && Directory.Exists(userPath)) { return userPath; } return null; } private static bool HasCSharpFiles(string directory) { try { return Directory.GetFiles(directory, "*.cs", SearchOption.AllDirectories).Length > 0; } catch { return false; } } private static async Task RunComplexityAnalysis(AIPluginRegistry registry, string projectPath) { Console.WriteLine("🔍 Running Complexity Analysis..."); try { var parameters = new Dictionary { ["path"] = projectPath, ["calculateCyclomatic"] = true, ["calculateCognitive"] = true, ["maxCyclomaticComplexity"] = 10, ["maxCognitiveComplexity"] = 15, ["generateSuggestions"] = true, ["includeMethodBreakdown"] = true }; var result = await registry.CallFunctionAsync("ComplexityAnalyzer", parameters); if (result.Success) { Console.WriteLine(" ✅ Complexity analysis completed"); PrintResultSummary("Complexity", result.Data); await SaveResultToFile("complexity-analysis.json", result.Data); } else { Console.WriteLine($" ❌ Complexity analysis failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($" ❌ Complexity analysis error: {ex.Message}"); } Console.WriteLine(); } private static async Task RunPerformanceAnalysis(AIPluginRegistry registry, string projectPath) { Console.WriteLine("⚡ Running Performance Analysis..."); try { var parameters = new Dictionary { ["path"] = projectPath, ["analyzeComplexity"] = true, ["checkLoops"] = true, ["analyzeMemory"] = true, ["checkDatabase"] = true, ["suggestCaching"] = true, ["analysisDepth"] = "comprehensive" }; var result = await registry.CallFunctionAsync("PerformanceAnalyzer", parameters); if (result.Success) { Console.WriteLine(" ✅ Performance analysis completed"); PrintResultSummary("Performance", result.Data); await SaveResultToFile("performance-analysis.json", result.Data); } else { Console.WriteLine($" ❌ Performance analysis failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($" ❌ Performance analysis error: {ex.Message}"); } Console.WriteLine(); } private static async Task RunTechnicalDebtAnalysis(AIPluginRegistry registry, string projectPath) { Console.WriteLine("💳 Running Technical Debt Analysis..."); try { var parameters = new Dictionary { ["projectPath"] = projectPath, ["calculateComplexityDebt"] = true, ["analyzeDocumentationDebt"] = true, ["checkDependencyDebt"] = true, ["analyzeTestDebt"] = true, ["generateImprovementPlan"] = true, ["trackTrends"] = true }; var result = await registry.CallFunctionAsync("TechnicalDebt", parameters); if (result.Success) { Console.WriteLine(" ✅ Technical debt analysis completed"); PrintResultSummary("Technical Debt", result.Data); await SaveResultToFile("technical-debt-analysis.json", result.Data); } else { Console.WriteLine($" ❌ Technical debt analysis failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($" ❌ Technical debt analysis error: {ex.Message}"); } Console.WriteLine(); } private static async Task RunArchitectureValidation(AIPluginRegistry registry, string projectPath) { Console.WriteLine("🏗️ Running Architecture Validation..."); try { var parameters = new Dictionary { ["projectPath"] = projectPath, ["architecturePattern"] = "auto", ["checkLayerBoundaries"] = true, ["checkCircularDependencies"] = true, ["validateNaming"] = true, ["checkAntiPatterns"] = true, ["generateDocumentation"] = true }; var result = await registry.CallFunctionAsync("ArchitectureValidator", parameters); if (result.Success) { Console.WriteLine(" ✅ Architecture validation completed"); PrintResultSummary("Architecture", result.Data); await SaveResultToFile("architecture-validation.json", result.Data); } else { Console.WriteLine($" ❌ Architecture validation failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($" ❌ Architecture validation error: {ex.Message}"); } Console.WriteLine(); } private static async Task RunTestAnalysis(AIPluginRegistry registry, string projectPath) { Console.WriteLine("🧪 Running Test Analysis..."); try { var parameters = new Dictionary { ["projectPath"] = projectPath, ["calculateCoverage"] = true, ["identifyUntested"] = true, ["analyzeTestQuality"] = true, ["generateTestStubs"] = true, ["suggestAdvancedTesting"] = true, ["checkRedundantTests"] = true }; var result = await registry.CallFunctionAsync("TestAnalysis", parameters); if (result.Success) { Console.WriteLine(" ✅ Test analysis completed"); PrintResultSummary("Test", result.Data); await SaveResultToFile("test-analysis.json", result.Data); } else { Console.WriteLine($" ❌ Test analysis failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($" ❌ Test analysis error: {ex.Message}"); } Console.WriteLine(); } private static async Task RunBehaviorAnalysis(AIPluginRegistry registry, string projectPath) { Console.WriteLine("🎭 Running Behavior Analysis..."); try { var parameters = new Dictionary { ["path"] = projectPath, ["generateSummaries"] = true, ["compareVersions"] = true, ["detectBreakingChanges"] = true, ["validateIntent"] = true, ["suggestTests"] = true }; var result = await registry.CallFunctionAsync("BehaviorAnalysis", parameters); if (result.Success) { Console.WriteLine(" ✅ Behavior analysis completed"); PrintResultSummary("Behavior", result.Data); await SaveResultToFile("behavior-analysis.json", result.Data); } else { Console.WriteLine($" ❌ Behavior analysis failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($" ❌ Behavior analysis error: {ex.Message}"); } Console.WriteLine(); } private static async Task GenerateComprehensiveReport(AIPluginRegistry registry, string projectPath) { Console.WriteLine("📋 Generating Comprehensive Analysis Report..."); try { var reportData = new { GeneratedAt = DateTime.UtcNow, ProjectPath = projectPath, AnalysisType = "Comprehensive Code Quality Assessment", PluginsUsed = new[] { "ComplexityAnalyzer - Cyclomatic and cognitive complexity analysis", "PerformanceAnalyzer - Performance bottleneck detection", "TechnicalDebt - Debt quantification and improvement planning", "ArchitectureValidator - Architectural pattern validation", "TestAnalysis - Test coverage and quality assessment", "BehaviorAnalysis - Code behavior and intent validation" }, Summary = new { TotalAnalysisPlugins = 6, AnalysisScope = "Full project analysis including complexity, performance, debt, architecture, testing, and behavior", OutputFiles = new[] { "complexity-analysis.json", "performance-analysis.json", "technical-debt-analysis.json", "architecture-validation.json", "test-analysis.json", "behavior-analysis.json" } }, Recommendations = new[] { "Review high-complexity methods identified in complexity analysis", "Address performance bottlenecks found in performance analysis", "Follow improvement plan from technical debt analysis", "Fix architecture violations found in validation", "Improve test coverage based on test analysis results", "Align code behavior with specifications per behavior analysis" }, NextSteps = new[] { "Prioritize issues by severity and impact", "Create development tasks for high-priority improvements", "Implement recommended refactoring and optimizations", "Re-run analysis to track progress", "Integrate analysis into CI/CD pipeline for continuous monitoring" } }; await SaveResultToFile("comprehensive-analysis-report.json", reportData); // Generate markdown report var markdownReport = GenerateMarkdownReport(reportData); await File.WriteAllTextAsync("analysis-report.md", markdownReport); Console.WriteLine(" ✅ Comprehensive report generated"); Console.WriteLine(" 📄 JSON Report: comprehensive-analysis-report.json"); Console.WriteLine(" 📝 Markdown Report: analysis-report.md"); } catch (Exception ex) { Console.WriteLine($" ❌ Report generation error: {ex.Message}"); } } private static void PrintResultSummary(string analysisType, object data) { try { var jsonElement = JsonSerializer.Deserialize(JsonSerializer.Serialize(data)); if (jsonElement.TryGetProperty("Summary", out var summary)) { Console.WriteLine($" 📊 {analysisType} Summary:"); PrintJsonProperties(summary, " "); } else if (jsonElement.TryGetProperty("OverallComplexityScore", out var score)) { Console.WriteLine($" 📊 {analysisType} Score: {score}"); } else { Console.WriteLine($" 📊 {analysisType} analysis data captured"); } } catch (Exception ex) { Console.WriteLine($" ⚠️ Could not parse {analysisType} summary: {ex.Message}"); } } private static void PrintJsonProperties(JsonElement element, string indent) { foreach (var property in element.EnumerateObject()) { var value = property.Value.ValueKind switch { JsonValueKind.String => property.Value.GetString(), JsonValueKind.Number => property.Value.GetRawText(), JsonValueKind.True => "true", JsonValueKind.False => "false", JsonValueKind.Array => $"[{property.Value.GetArrayLength()} items]", JsonValueKind.Object => "[object]", _ => property.Value.GetRawText() }; Console.WriteLine($"{indent}{property.Name}: {value}"); } } private static async Task SaveResultToFile(string filename, object data) { try { var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); await File.WriteAllTextAsync(filename, json); Console.WriteLine($" 💾 Results saved to: {filename}"); } catch (Exception ex) { Console.WriteLine($" ❌ Failed to save {filename}: {ex.Message}"); } } private static string GenerateMarkdownReport(object reportData) { return @"# MarketAlly AI Plugin Analysis Report ## Executive Summary This report presents a comprehensive analysis of the codebase using the MarketAlly AI Plugin Analysis toolkit. The analysis covers six key areas: complexity, performance, technical debt, architecture, testing, and behavior. ## Analysis Overview | Analysis Type | Status | Output File | |---------------|--------|-------------| | Complexity Analysis | ✅ Complete | `complexity-analysis.json` | | Performance Analysis | ✅ Complete | `performance-analysis.json` | | Technical Debt Analysis | ✅ Complete | `technical-debt-analysis.json` | | Architecture Validation | ✅ Complete | `architecture-validation.json` | | Test Analysis | ✅ Complete | `test-analysis.json` | | Behavior Analysis | ✅ Complete | `behavior-analysis.json` | ## Key Findings ### 🔍 Complexity Analysis - Analyzed cyclomatic and cognitive complexity - Identified high-complexity methods requiring refactoring - Generated specific reduction suggestions ### ⚡ Performance Analysis - Detected performance bottlenecks and optimization opportunities - Analyzed loop efficiency and memory allocation patterns - Suggested caching and database optimization strategies ### 💳 Technical Debt Analysis - Quantified debt across complexity, documentation, dependencies, and testing - Generated prioritized improvement plan with effort estimates - Tracked debt trends over time ### 🏗️ Architecture Validation - Validated architectural patterns and layer boundaries - Detected circular dependencies and anti-patterns - Assessed naming convention compliance ### 🧪 Test Analysis - Evaluated test coverage and quality - Identified untested functions and quality issues - Suggested advanced testing strategies ### 🎭 Behavior Analysis - Analyzed code behavior against specifications - Detected semantic drift and breaking changes - Generated behavior test suggestions ## Recommendations 1. **Immediate Actions** - Review and address high-severity issues from all analyses - Implement suggested refactoring for complex methods - Fix critical architecture violations 2. **Short-term Improvements** - Follow technical debt improvement plan - Enhance test coverage based on analysis results - Optimize performance bottlenecks 3. **Long-term Strategy** - Integrate analysis tools into CI/CD pipeline - Establish coding standards based on findings - Regular re-analysis to track progress ## Detailed Results For detailed analysis results, please refer to the individual JSON files generated for each analysis type. --- *Report generated by MarketAlly AI Plugin Analysis Toolkit* *Generated on: " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss UTC") + @"* "; } } // Sample test classes to analyze if no project is provided public class SampleComplexClass { private readonly string _connectionString; private readonly ILogger _logger; public SampleComplexClass(string connectionString, ILogger logger) { _connectionString = connectionString; _logger = logger; } // High complexity method public async Task ProcessComplexBusinessLogic(int type, string data, bool validate) { if (string.IsNullOrEmpty(data)) throw new ArgumentException("Data cannot be null or empty"); var result = ""; for (int i = 0; i < data.Length; i++) { if (validate) { if (char.IsDigit(data[i])) { if (type == 1) { result += data[i]; } else if (type == 2) { result += (char)(data[i] + 1); } else { switch (type) { case 3: result += data[i].ToString().ToUpper(); break; case 4: result += data[i].ToString().ToLower(); break; default: result += data[i]; break; } } } else if (char.IsLetter(data[i])) { if (type == 1 || type == 2) { result += data[i].ToString().ToUpper(); } else { result += data[i].ToString().ToLower(); } } } else { result += data[i]; } } return result; } // Database access method (simulated without SqlClient dependency) public async Task> GetDataFromDatabase(string query) { var results = new List(); try { // Simulate database access without SqlClient dependency _logger?.LogInformation("Executing database query: {Query}", query); // Simulate async database operation await Task.Delay(100); // Simulate some results results.Add("Sample Result 1"); results.Add("Sample Result 2"); results.Add("Sample Result 3"); _logger?.LogInformation("Retrieved {Count} records", results.Count); } catch (Exception ex) { _logger?.LogError(ex, "Database query failed"); throw; } return results; } // Method lacking documentation public bool ValidateInput(string input) { return !string.IsNullOrEmpty(input) && input.Length > 3; } // Method with file system access public async Task ProcessFileAsync(string filePath) { if (File.Exists(filePath)) { var content = await File.ReadAllTextAsync(filePath); Console.WriteLine($"Processing file: {filePath}"); return content.ToUpperInvariant(); } return string.Empty; } // Method with network communication simulation public async Task FetchDataFromApiAsync(string endpoint) { try { // Simulate HTTP client usage await Task.Delay(200); // Simulate network delay _logger?.LogInformation("Fetching data from: {Endpoint}", endpoint); // Simulate API response return $"{{\"data\": \"response from {endpoint}\"}}"; } catch (Exception ex) { _logger?.LogError(ex, "API call failed for endpoint: {Endpoint}", endpoint); throw; } } } public class UtilityHelper { public static string FormatString(string input) { return input?.Trim().ToLowerInvariant() ?? ""; } public static int CalculateSum(int[] numbers) { int sum = 0; for (int i = 0; i < numbers.Length; i++) { sum += numbers[i]; } return sum; } } }