using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Dacryptero.DB.Creation;
using Dacryptero.Web;
using MaxLib.WebServer;

namespace Dacryptero.Web;

public class SecurityMasterKey : WebService
{
    public SecurityMasterKey()
        : base(ServerStage.CreateDocument)
    {
    }

    public override bool CanWorkWith(WebProgressTask task)
    {
        var param = task.Request.Location.GetParameter;
        return task.Request.Location.IsUrl(new []{ "security", "master-key" })
            && param.ContainsKey("session")
            && param.ContainsKey("key");
    }

    public override async Task ProgressTask(WebProgressTask task)
    {
        var session = await WebSocketConnection.FindFromSessionId(
            task.Request.Location.GetParameter["session"]
        ).ConfigureAwait(false);

        var request = session is null ? null : session.NewDBInfo.TryGetValue(
            task.Request.Location.GetParameter["key"],
            out NewDBInfo? info_
        ) ? info_ : null;

        if (request is null)
        {
            task.Response.StatusCode = HttpStateCode.Forbidden;
            await Tools.AddTemplate(task, "invalid-master-key.html")
                .ConfigureAwait(false);
            return;
        }

        await Tools.AddTemplate(task, "show-master-key.html",
            new Dictionary<string, string>
            {
                { "NAME", System.Net.WebUtility.HtmlEncode(request.Name) },
                { "SCHEMA", System.Net.WebUtility.HtmlEncode(request.Schema) },
                { "KEY", GetKeyString(request.MasterKey.Span) },
                { "DATE", DateTime.UtcNow.ToString("s").Replace('T', ' ') + " UTC" },
            }
        ).ConfigureAwait(false);
    }

    private string GetKeyString(ReadOnlySpan<byte> data)
    {
        var sb = new StringBuilder(data.Length * 3);
        for (int i = 0; i < data.Length; i += 4)
        {
            var max = Math.Min(i + 4, data.Length);
            sb.Append(Convert.ToHexString(data[i..max]));
            sb.Append(' ');
        }
        return sb.ToString();
    }
}