var builder = WebApplication.CreateBuilder(args);

// Configure clients
builder.Services.AddHttpClient("GoBackend", client => {
    client.BaseAddress = new Uri("http://localhost:8080");
});

var app = builder.Build();

// Handle trailing slash redirects
app.Use(async (context, next) => {
    if (context.Request.Path.Equals("/lst", StringComparison.OrdinalIgnoreCase)) {
        context.Response.Redirect("/lst/", permanent: true);
        return;
    }
    await next();
});

// Proxy all requests to Go backend
app.Use(async (context, next) => {
    // Skip special paths
    if (context.Request.Path.StartsWithSegments("/.well-known")) {
        await next();
        return;
    }

    var client = context.RequestServices.GetRequiredService<IHttpClientFactory>()
        .CreateClient("GoBackend");
    
    try {
        var request = new HttpRequestMessage(
            new HttpMethod(context.Request.Method),
            context.Request.Path + context.Request.QueryString);

        // Copy headers
        foreach (var header in context.Request.Headers) {
            if (!request.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray())) {
                request.Content ??= new StreamContent(context.Request.Body);
                request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
            }
        }

        if (context.Request.ContentLength > 0) {
            request.Content = new StreamContent(context.Request.Body);
        }

        var response = await client.SendAsync(request);
        context.Response.StatusCode = (int)response.StatusCode;
        
        foreach (var header in response.Headers) {
            context.Response.Headers[header.Key] = header.Value.ToArray();
        }

        if (response.Content.Headers.ContentType != null) {
            context.Response.ContentType = response.Content.Headers.ContentType.ToString();
        }

        await response.Content.CopyToAsync(context.Response.Body);
    }
    catch (HttpRequestException) {
        context.Response.StatusCode = 502;
    }
});

app.Run();