using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using SqrtSpace.SpaceTime.Core;
using SqrtSpace.SpaceTime.Diagnostics;
namespace SqrtSpace.SpaceTime.AspNetCore;
///
/// Extension methods for configuring SpaceTime services
///
public static class ServiceCollectionExtensions
{
///
/// Adds SpaceTime services to the service collection
///
public static IServiceCollection AddSpaceTime(
this IServiceCollection services,
Action? configureOptions = null)
{
var options = new SpaceTimeServiceOptions();
configureOptions?.Invoke(options);
// Register options
services.AddSingleton(options);
// Add checkpoint services if enabled
if (options.EnableCheckpointing)
{
services.AddSingleton(options.CheckpointOptions);
}
// Add streaming services if enabled
if (options.EnableStreaming)
{
services.AddSingleton(options.StreamingOptions);
}
return services;
}
///
/// Adds SpaceTime middleware to the pipeline
///
public static IApplicationBuilder UseSpaceTime(this IApplicationBuilder app)
{
var options = app.ApplicationServices.GetService();
if (options == null)
{
throw new InvalidOperationException("SpaceTime services not registered. Call AddSpaceTime() in ConfigureServices.");
}
if (options.EnableCheckpointing)
{
var checkpointOptions = app.ApplicationServices.GetRequiredService();
app.UseMiddleware(checkpointOptions);
}
if (options.EnableStreaming)
{
var streamingOptions = app.ApplicationServices.GetRequiredService();
app.UseMiddleware(streamingOptions);
}
return app;
}
///
/// Maps SpaceTime diagnostic and monitoring endpoints
///
public static IApplicationBuilder UseSpaceTimeEndpoints(this IApplicationBuilder app)
{
app.UseEndpoints(endpoints =>
{
// Health check endpoint
endpoints.MapGet("/spacetime/health", async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("OK");
});
// Metrics endpoint (for Prometheus scraping)
endpoints.MapGet("/spacetime/metrics", async context =>
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("# SpaceTime metrics endpoint\n");
await context.Response.WriteAsync("# Configure OpenTelemetry with Prometheus exporter for metrics\n");
});
// Diagnostics report endpoint
endpoints.MapGet("/spacetime/diagnostics", async context =>
{
var diagnostics = context.RequestServices.GetService();
if (diagnostics != null)
{
var report = await diagnostics.GenerateReportAsync(TimeSpan.FromHours(1));
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(report);
}
else
{
context.Response.StatusCode = 404;
await context.Response.WriteAsync("Diagnostics not configured");
}
});
// Configuration endpoint
endpoints.MapGet("/spacetime/config", async context =>
{
var options = context.RequestServices.GetService();
if (options != null)
{
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(options);
}
else
{
context.Response.StatusCode = 404;
await context.Response.WriteAsync("Configuration not found");
}
});
});
return app;
}
}
///
/// Options for SpaceTime services
///
public class SpaceTimeServiceOptions
{
///
/// Enable checkpointing middleware
///
public bool EnableCheckpointing { get; set; } = true;
///
/// Enable streaming optimizations
///
public bool EnableStreaming { get; set; } = true;
///
/// Options for checkpointing
///
public CheckpointOptions CheckpointOptions { get; set; } = new();
///
/// Options for streaming
///
public ResponseStreamingOptions StreamingOptions { get; set; } = new();
///
/// Directory for storing checkpoints
///
public string CheckpointDirectory { get; set; } = Path.Combine(Path.GetTempPath(), "spacetime-checkpoints");
///
/// Checkpointing strategy to use
///
public CheckpointStrategy CheckpointStrategy { get; set; } = CheckpointStrategy.SqrtN;
///
/// Interval for checkpointing operations
///
public TimeSpan CheckpointInterval { get; set; } = TimeSpan.FromSeconds(30);
///
/// Directory for external storage operations
///
public string ExternalStorageDirectory { get; set; } = Path.Combine(Path.GetTempPath(), "spacetime-storage");
///
/// Default strategy for space-time operations
///
public SpaceTimeStrategy DefaultStrategy { get; set; } = SpaceTimeStrategy.SqrtN;
///
/// Default chunk size for streaming operations
///
public int DefaultChunkSize { get; set; } = 1024;
///
/// Buffer size for streaming operations
///
public int StreamingBufferSize { get; set; } = 8192;
}
///
/// Strategies for space-time tradeoffs
///
public enum SpaceTimeStrategy
{
/// Use √n space strategy
SqrtN,
/// Use O(1) space strategy
Constant,
/// Use O(log n) space strategy
Logarithmic,
/// Use O(n) space strategy
Linear
}