using MarketAlly.AIPlugin; using MarketAlly.AIPlugin.Refactoring.Plugins; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; using System.Text.Json; using System.Threading.Tasks; namespace MarketAlly.AIPlugin.Refactoring.TestConsole; /// /// Test console for the ReadmeGeneratorPlugin /// class ReadmeTestProgram { static async Task Main(string[] args) { var host = CreateHost(); var testService = host.Services.GetRequiredService(); try { ShowWelcome(); // If command line arguments provided, execute them first if (args.Length > 0) { await ExecuteCommand(args, testService); Console.WriteLine(); } // Start interactive loop while (true) { try { Console.Write("ReadmeTest> "); var input = Console.ReadLine(); if (string.IsNullOrWhiteSpace(input)) continue; if (input.Trim() == "/exit" || input.Trim() == "exit") { Console.WriteLine("[INFO] Goodbye!"); break; } if (input.Trim() == "/help" || input.Trim() == "help") { ShowHelp(); continue; } var commandArgs = ParseInput(input); if (commandArgs.Length == 0) continue; await ExecuteCommand(commandArgs, testService); Console.WriteLine(); } catch (Exception ex) { Console.WriteLine($"[ERROR] Command error: {ex.Message}"); Console.WriteLine(); } } return 0; } catch (Exception ex) { Console.WriteLine($"[ERROR] Application error: {ex.Message}"); var logger = host.Services.GetRequiredService>(); logger.LogError(ex, "Application failed"); return 1; } } private static async Task ExecuteCommand(string[] args, ReadmeTestService service) { if (args.Length == 0) { ShowHelp(); return; } var command = args[0].ToLower(); switch (command) { case "generate": case "readme": await HandleGenerateCommand(args, service); break; case "preview": await HandlePreviewCommand(args, service); break; case "test-self": await service.TestOnSelfAsync(); break; case "test-types": await service.TestProjectTypesAsync(); break; case "create-samples": await service.CreateSampleProjectsAsync(); break; case "help": ShowHelp(); break; default: Console.WriteLine($"[ERROR] Unknown command: {command}"); ShowHelp(); break; } } private static async Task HandleGenerateCommand(string[] args, ReadmeTestService service) { string projectPath = GetPathFromArgs(args, "Enter project path: "); if (string.IsNullOrEmpty(projectPath)) return; string projectType = GetValueFromArgs(args, "--type", "auto"); bool apply = args.Contains("--apply"); bool includeApi = !args.Contains("--no-api"); bool includeArch = !args.Contains("--no-arch"); bool includeSetup = !args.Contains("--no-setup"); bool includeExamples = !args.Contains("--no-examples"); await service.GenerateReadmeAsync(projectPath, projectType, apply, includeApi, includeArch, includeSetup, includeExamples); } private static async Task HandlePreviewCommand(string[] args, ReadmeTestService service) { string projectPath = GetPathFromArgs(args, "Enter project path: "); if (string.IsNullOrEmpty(projectPath)) return; string projectType = GetValueFromArgs(args, "--type", "auto"); await service.PreviewReadmeAsync(projectPath, projectType); } private static string GetPathFromArgs(string[] args, string prompt) { var pathIndex = Array.IndexOf(args, "--path"); if (pathIndex >= 0 && pathIndex + 1 < args.Length) { return args[pathIndex + 1]; } Console.Write(prompt); var path = Console.ReadLine()?.Trim(); return string.IsNullOrEmpty(path) ? null : path; } private static string GetValueFromArgs(string[] args, string flag, string defaultValue = "") { var index = Array.IndexOf(args, flag); if (index >= 0 && index + 1 < args.Length) { return args[index + 1]; } return defaultValue; } private static string[] ParseInput(string input) { var parts = new List(); var current = new System.Text.StringBuilder(); bool inQuotes = false; foreach (char c in input) { if (c == '"') { inQuotes = !inQuotes; continue; } if (char.IsWhiteSpace(c) && !inQuotes) { if (current.Length > 0) { parts.Add(current.ToString()); current.Clear(); } } else { current.Append(c); } } if (current.Length > 0) { parts.Add(current.ToString()); } return parts.ToArray(); } private static void ShowWelcome() { Console.WriteLine("MarketAlly AI Plugin README Generator Test Console"); Console.WriteLine("=" + new string('=', 54)); Console.WriteLine(); Console.WriteLine("Test suite for the ReadmeGeneratorPlugin"); Console.WriteLine("Type 'help' for commands or 'exit' to quit"); Console.WriteLine(); } private static void ShowHelp() { Console.WriteLine(); Console.WriteLine("Available commands:"); Console.WriteLine(" generate [--path ] [--type ] [--apply] Generate README for project"); Console.WriteLine(" preview [--path ] [--type ] Preview README content"); Console.WriteLine(" test-self Test on this project"); Console.WriteLine(" test-types Test different project types"); Console.WriteLine(" create-samples Create sample projects"); Console.WriteLine(" help Show this help"); Console.WriteLine(" exit Exit application"); Console.WriteLine(); Console.WriteLine("Project types: auto, library, application, tool, maui"); Console.WriteLine(); Console.WriteLine("Flags:"); Console.WriteLine(" --apply Apply changes and create README.md"); Console.WriteLine(" --no-api Skip API documentation"); Console.WriteLine(" --no-arch Skip architecture section"); Console.WriteLine(" --no-setup Skip setup instructions"); Console.WriteLine(" --no-examples Skip usage examples"); Console.WriteLine(); Console.WriteLine("Examples:"); Console.WriteLine(" generate --path \"C:\\MyProject\" --type library --apply"); Console.WriteLine(" preview --path \"C:\\MyMauiApp\" --type maui"); Console.WriteLine(" test-self"); Console.WriteLine(); } private static IHost CreateHost() { return Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { services.AddLogging(builder => { builder.AddConsole(); builder.SetMinimumLevel(LogLevel.Information); }); services.AddSingleton(); services.AddTransient(); }) .Build(); } } /// /// Service for testing the ReadmeGeneratorPlugin /// public class ReadmeTestService { private readonly AIPluginRegistry _pluginRegistry; private readonly ILogger _logger; public ReadmeTestService(AIPluginRegistry pluginRegistry, ILogger logger) { _pluginRegistry = pluginRegistry; _logger = logger; SetupPlugins(); } private void SetupPlugins() { _pluginRegistry.RegisterPlugin(new ReadmeGeneratorPlugin()); _logger.LogInformation("Registered ReadmeGeneratorPlugin"); } public async Task GenerateReadmeAsync(string projectPath, string projectType, bool apply, bool includeApi, bool includeArch, bool includeSetup, bool includeExamples) { Console.WriteLine($"[INFO] Generating README for: {projectPath}"); Console.WriteLine($"[INFO] Project type: {projectType}"); Console.WriteLine($"[INFO] Apply changes: {apply}"); Console.WriteLine(new string('=', 60)); try { var parameters = new Dictionary { ["projectPath"] = projectPath, ["projectType"] = projectType, ["includeApiDocs"] = includeApi, ["includeArchitecture"] = includeArch, ["includeSetup"] = includeSetup, ["includeExamples"] = includeExamples, ["applyChanges"] = apply }; var result = await _pluginRegistry.CallFunctionAsync("ReadmeGenerator", parameters); if (result.Success) { Console.WriteLine("[SUCCESS] README generation completed!"); DisplayReadmeResults(result.Data); } else { Console.WriteLine($"[ERROR] Generation failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($"[ERROR] Test failed: {ex.Message}"); } } public async Task PreviewReadmeAsync(string projectPath, string projectType) { Console.WriteLine($"[PREVIEW] README for: {projectPath}"); Console.WriteLine($"[INFO] Project type: {projectType}"); Console.WriteLine(new string('=', 60)); try { var parameters = new Dictionary { ["projectPath"] = projectPath, ["projectType"] = projectType, ["applyChanges"] = false }; var result = await _pluginRegistry.CallFunctionAsync("ReadmeGenerator", parameters); if (result.Success) { Console.WriteLine("[SUCCESS] README preview generated!"); DisplayReadmeResults(result.Data); // Show preview content var resultJson = JsonSerializer.Serialize(result.Data, new JsonSerializerOptions { WriteIndented = true }); var resultElement = JsonSerializer.Deserialize(resultJson); if (resultElement.TryGetProperty("PreviewContent", out var previewContent)) { Console.WriteLine("\n[PREVIEW CONTENT]"); Console.WriteLine(new string('-', 40)); Console.WriteLine(previewContent.GetString()); } } else { Console.WriteLine($"[ERROR] Preview failed: {result.Message}"); } } catch (Exception ex) { Console.WriteLine($"[ERROR] Preview failed: {ex.Message}"); } } public async Task TestOnSelfAsync() { Console.WriteLine("[TEST] Testing README generation on this project"); Console.WriteLine(new string('=', 60)); // Get the current project directory var currentDir = Directory.GetCurrentDirectory(); // Look for project file in current or parent directories var projectPath = FindProjectDirectory(currentDir); if (projectPath == null) { Console.WriteLine("[ERROR] Could not find project file in current directory or parents"); return; } Console.WriteLine($"[INFO] Found project at: {projectPath}"); await GenerateReadmeAsync(projectPath, "auto", false, true, true, true, true); } public async Task TestProjectTypesAsync() { Console.WriteLine("[TEST] Testing different project types"); Console.WriteLine(new string('=', 60)); await CreateSampleProjectsAsync(); var sampleDir = Path.Combine(Directory.GetCurrentDirectory(), "ReadmeSamples"); if (!Directory.Exists(sampleDir)) { Console.WriteLine("[ERROR] Sample directory not found"); return; } var testCases = new[] { ("LibrarySample", "library"), ("ApplicationSample", "application"), ("ToolSample", "tool"), ("MauiSample", "maui") }; foreach (var (projectName, projectType) in testCases) { var projectPath = Path.Combine(sampleDir, projectName); if (Directory.Exists(projectPath)) { Console.WriteLine($"\n[TESTING] {projectType.ToUpper()} project type"); Console.WriteLine(new string('-', 30)); await PreviewReadmeAsync(projectPath, projectType); } } } public async Task CreateSampleProjectsAsync() { Console.WriteLine("[INFO] Creating sample projects for testing..."); var sampleDir = Path.Combine(Directory.GetCurrentDirectory(), "ReadmeSamples"); if (Directory.Exists(sampleDir)) { Directory.Delete(sampleDir, true); } Directory.CreateDirectory(sampleDir); // Create Library Sample await CreateLibrarySample(Path.Combine(sampleDir, "LibrarySample")); // Create Application Sample await CreateApplicationSample(Path.Combine(sampleDir, "ApplicationSample")); // Create Tool Sample await CreateToolSample(Path.Combine(sampleDir, "ToolSample")); // Create MAUI Sample await CreateMauiSample(Path.Combine(sampleDir, "MauiSample")); Console.WriteLine($"[SUCCESS] Created sample projects in: {sampleDir}"); } private async Task CreateLibrarySample(string projectPath) { Directory.CreateDirectory(projectPath); var projectContent = @" net8.0 Library latest "; await File.WriteAllTextAsync(Path.Combine(projectPath, "LibrarySample.csproj"), projectContent); var serviceContent = @"using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; namespace LibrarySample { /// /// Main service for library operations /// public class LibraryService : ILibraryService { private readonly ILogger _logger; public LibraryService(ILogger logger) { _logger = logger; } /// /// Processes data asynchronously /// public async Task ProcessDataAsync(string input, int count) { _logger.LogInformation(""Processing data: {Input}"", input); await Task.Delay(100); return $""Processed: {input} x {count}""; } /// /// Validates input data /// public bool ValidateInput(string input) { return !string.IsNullOrWhiteSpace(input); } } /// /// Interface for library service /// public interface ILibraryService { Task ProcessDataAsync(string input, int count); bool ValidateInput(string input); } }"; await File.WriteAllTextAsync(Path.Combine(projectPath, "LibraryService.cs"), serviceContent); } private async Task CreateApplicationSample(string projectPath) { Directory.CreateDirectory(projectPath); var projectContent = @" net8.0 enable "; await File.WriteAllTextAsync(Path.Combine(projectPath, "ApplicationSample.csproj"), projectContent); var programContent = @"using ApplicationSample.Services; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddScoped(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); namespace ApplicationSample.Services { public interface IDataService { Task GetDataAsync(); } public class DataService : IDataService { public async Task GetDataAsync() { await Task.Delay(10); return new { Message = ""Hello from ApplicationSample"", Timestamp = DateTime.UtcNow }; } } }"; await File.WriteAllTextAsync(Path.Combine(projectPath, "Program.cs"), programContent); } private async Task CreateToolSample(string projectPath) { Directory.CreateDirectory(projectPath); var projectContent = @" Exe net8.0 true toolsample "; await File.WriteAllTextAsync(Path.Combine(projectPath, "ToolSample.csproj"), projectContent); var programContent = @"using System; using System.CommandLine; using System.IO; using System.Threading.Tasks; namespace ToolSample { class Program { /// /// Main entry point for the tool /// static async Task Main(string[] args) { var rootCommand = new RootCommand(""A sample command-line tool""); var processCommand = new Command(""process"", ""Process a file""); var inputOption = new Option(""--input"", ""Input file to process""); var outputOption = new Option(""--output"", ""Output file""); processCommand.AddOption(inputOption); processCommand.AddOption(outputOption); processCommand.SetHandler(ProcessFileAsync, inputOption, outputOption); rootCommand.AddCommand(processCommand); return await rootCommand.InvokeAsync(args); } /// /// Processes a file asynchronously /// static async Task ProcessFileAsync(FileInfo input, FileInfo output) { Console.WriteLine($""Processing {input.Name} -> {output.Name}""); if (!input.Exists) { Console.WriteLine(""Input file does not exist""); return; } var content = await File.ReadAllTextAsync(input.FullName); var processedContent = content.ToUpperInvariant(); await File.WriteAllTextAsync(output.FullName, processedContent); Console.WriteLine(""File processed successfully""); } } }"; await File.WriteAllTextAsync(Path.Combine(projectPath, "Program.cs"), programContent); } private async Task CreateMauiSample(string projectPath) { Directory.CreateDirectory(projectPath); var projectContent = @" net8.0-android;net8.0-ios;net8.0-maccatalyst;net8.0-windows10.0.19041.0 Exe MauiSample true true enable "; await File.WriteAllTextAsync(Path.Combine(projectPath, "MauiSample.csproj"), projectContent); var appContent = @"using Microsoft.Extensions.Logging; namespace MauiSample; /// /// Main MAUI application class /// public partial class App : Application { public App() { InitializeComponent(); MainPage = new AppShell(); } }"; await File.WriteAllTextAsync(Path.Combine(projectPath, "App.xaml.cs"), appContent); var mainPageContent = @"using Microsoft.Extensions.Logging; namespace MauiSample; /// /// Main page for the MAUI application /// public partial class MainPage : ContentPage { private readonly ILogger _logger; private int _clickCount = 0; public MainPage(ILogger logger) { _logger = logger; InitializeComponent(); } /// /// Handles the counter button click event /// private void OnCounterClicked(object sender, EventArgs e) { _clickCount++; if (_clickCount == 1) CounterBtn.Text = $""Clicked {_clickCount} time""; else CounterBtn.Text = $""Clicked {_clickCount} times""; _logger.LogInformation(""Button clicked {ClickCount} times"", _clickCount); SemanticScreenReader.Announce(CounterBtn.Text); } /// /// Resets the counter to zero /// public void ResetCounter() { _clickCount = 0; CounterBtn.Text = ""Click me""; _logger.LogInformation(""Counter reset""); } }"; await File.WriteAllTextAsync(Path.Combine(projectPath, "MainPage.xaml.cs"), mainPageContent); var mauiProgramContent = @"using Microsoft.Extensions.Logging; namespace MauiSample; /// /// MAUI program configuration /// public static class MauiProgram { /// /// Creates and configures the MAUI app /// public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp() .ConfigureFonts(fonts => { fonts.AddFont(""OpenSans-Regular.ttf"", ""OpenSansRegular""); }); builder.Services.AddMauiBlazorWebView(); #if DEBUG builder.Services.AddLogging(logging => logging.AddDebug()); #endif builder.Services.AddSingleton(); builder.Services.AddTransient(); return builder.Build(); } } /// /// Service interface for data operations /// public interface IDataService { Task GetDataAsync(); Task SaveDataAsync(string data); } /// /// Implementation of data service /// public class DataService : IDataService { private readonly ILogger _logger; public DataService(ILogger logger) { _logger = logger; } /// /// Retrieves data asynchronously /// public async Task GetDataAsync() { _logger.LogInformation(""Getting data...""); await Task.Delay(100); return ""Sample data from MAUI app""; } /// /// Saves data asynchronously /// public async Task SaveDataAsync(string data) { _logger.LogInformation(""Saving data: {Data}"", data); await Task.Delay(50); } }"; await File.WriteAllTextAsync(Path.Combine(projectPath, "MauiProgram.cs"), mauiProgramContent); } private string FindProjectDirectory(string startPath) { var currentDir = new DirectoryInfo(startPath); while (currentDir != null) { // Look for .csproj files var projectFiles = currentDir.GetFiles("*.csproj"); if (projectFiles.Any()) { return currentDir.FullName; } // Look for .sln files var solutionFiles = currentDir.GetFiles("*.sln"); if (solutionFiles.Any()) { return currentDir.FullName; } currentDir = currentDir.Parent; } return null; } private void DisplayReadmeResults(object data) { var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); var resultElement = JsonSerializer.Deserialize(json); Console.WriteLine("\n[RESULTS]"); DisplayJsonProperty(resultElement, "Message"); DisplayJsonProperty(resultElement, "ProjectType"); DisplayJsonProperty(resultElement, "FilesAnalyzed"); DisplayJsonProperty(resultElement, "ContentLength"); DisplayJsonProperty(resultElement, "ChangesApplied"); if (resultElement.TryGetProperty("ReadmePath", out var readmePath)) { Console.WriteLine($" README saved to: {readmePath.GetString()}"); } if (resultElement.TryGetProperty("Sections", out var sections) && sections.ValueKind == JsonValueKind.Array) { Console.WriteLine(" Sections included:"); foreach (var section in sections.EnumerateArray()) { Console.WriteLine($" - {section.GetString()}"); } } } private void DisplayJsonProperty(JsonElement element, string propertyName) { if (element.TryGetProperty(propertyName, out var property)) { var value = property.ValueKind switch { JsonValueKind.String => property.GetString(), JsonValueKind.Number => property.GetDouble().ToString("F0"), JsonValueKind.True => "True", JsonValueKind.False => "False", _ => property.ToString() }; Console.WriteLine($" {propertyName}: {value}"); } } }