using System.Net.Sockets;
using System.Text;
using System.Web;

namespace Shoko;

[Protocol("spartan")]
class SpartanProtoHandler : ProtoHandler
{
    public SpartanProtoHandler(Uri url)
    {
        URL = url;
    }

    public override async Task Load()
    {
        var file = URL.AbsolutePath;

        if(!file.StartsWith("/")) file = "/"+file;

        var data = URL.Query;
        if(data.StartsWith("?")) data.Remove(0,1);

        var query = Encoding.UTF8.GetBytes(data);

        var uri = Encoding.UTF8.GetBytes($"{URL.Host} {HttpUtility.UrlDecode(file)} {query.Length}\r\n");

        var tcp = new TcpClient(URL.Host, URL.Port < 0 ? 300 : URL.Port);

        var stream = tcp.GetStream();
        await stream.WriteAsync(uri);
        if(query.Length > 0)
            await stream.WriteAsync(query);

        var reader = new StreamReader(stream);
        var header = reader.ReadLine();

        var meta = header.Split(" ", 2, StringSplitOptions.TrimEntries);
        Status = meta[0];

        MediaType = "text/plain";

        if(Status.StartsWith('2'))
        {
            if(meta.Length > 1)
            {
                var dict = new Dictionary<string, string>();
                var type = meta[1].Split(";", StringSplitOptions.TrimEntries).ToList();
                MediaType = type[0];

                foreach (var item in type)
                {
                    var val = item.Split("=", 2);
                    dict[val[0]] = val.Length > 1 ? val[1] : "";
                }

                MediaTypeParams = dict;
            }
            Content = await Download(stream);
        }
        else
        {
            byte[] content = new byte[]{};
            if(meta.Length > 1)
            {
                if(Status.StartsWith('3'))
                {
                    meta[1] = "=> "+meta[1];
                    MediaType = "text/gemini";
                }
                content = Encoding.UTF8.GetBytes(meta[1]);
            }
            Content = new MemoryStream(content);
        }
        OnLoaded();
    }

    public override void Render()
    {
    }
}