using System.Text;

namespace LowLevelGuyCom.Middleware;

public sealed class CurlLandingMiddleware(
    RequestDelegate next)
{
    public async Task Invoke(HttpContext context)
    {
        if (!HttpMethods.IsGet(context.Request.Method) || context.Request.Path != "/")
        {
            await next(context);
            return;
        }

        if (WantsTerminalView(context.Request))
        {
            context.Response.StatusCode = StatusCodes.Status200OK;
            context.Response.ContentType = "text/plain; charset=utf-8";
            context.Response.Headers.CacheControl = "no-cache";

            string ansi = BuildLowLevelGuyAnsi();

            await context.Response.WriteAsync(ansi, Encoding.UTF8);
            return;
        }

        await next(context);
    }

    private static bool WantsTerminalView(HttpRequest request)
    {
        string userAgent = request.Headers.UserAgent.ToString();

        if (!string.IsNullOrWhiteSpace(userAgent))
        {
            string lowerUserAgent = userAgent.ToLowerInvariant();
            if (lowerUserAgent.Contains("curl"))
                return true;
        }

        return false;
    }

    private static string BuildLowLevelGuyAnsi()
    {
        const string ESC = "\u001b";
        string Arch(string s) => ESC + "[38;2;97;214;214m" + s + ESC + "[0m";
        string Dim(string s) => ESC + "[38;2;140;140;140m" + s + ESC + "[0m";
        string Bold(string s) => ESC + "[1m" + s + ESC + "[0m";

        var sb = new StringBuilder();

        sb.AppendLine(Arch("           /\\"));
        sb.AppendLine(Arch("          /  \\") + "        " + Bold("LOW LEVEL GUY"));
        sb.AppendLine(Arch("         /\\   \\") + "       " + Dim("arch vibes • low-level content"));
        sb.AppendLine(Arch("        /      \\"));
        sb.AppendLine(Arch("       /   ,,   \\") + "      C • ASM • Linux");
        sb.AppendLine(Arch("      /   |  |  -\\") + "     no magic • just bytes");
        sb.AppendLine(Arch("     /_-''    ''-_\\" ));
        sb.AppendLine();
        sb.AppendLine(Dim("────────────────────────────────────────────────────────"));
        sb.AppendLine();
        sb.AppendLine("$ curl " + Arch("low-level-guy.com"));
        sb.AppendLine("$ web  " + Arch("https://low-level-guy.com"));
        sb.AppendLine();
        sb.AppendLine("• systems programming");
        sb.AppendLine("• graphics from scratch");
        sb.AppendLine("• compilers, loaders, kernels");
        sb.AppendLine();
        sb.AppendLine(Dim("// operating below the abstraction layer"));
        sb.AppendLine();

        return sb.ToString();
    }
}

public static class CurlLandingMiddlewareExtensions
{
    public static IApplicationBuilder UseCurlLanding(this IApplicationBuilder app)
    {
        return app.UseMiddleware<CurlLandingMiddleware>();
    }
}