using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Diagnostics;

class Program
{
    static async Task Main(string[] args)
    {
        string username = Environment.GetEnvironmentVariable("SNEK_USERNAME") ?? "anonymous";
        string password = Environment.GetEnvironmentVariable("SNEK_PASSWORD") ?? "anonymous";

        using (var client = new ClientWebSocket())
        {
            Uri serverUri = new Uri("wss://snek.molodetz.nl/rpc.ws");
            await client.ConnectAsync(serverUri, CancellationToken.None);

            var jsonMessage = JsonConvert.SerializeObject(new {
                method = "login",
                args = new[] { username, password }
            });

            var bytes = Encoding.UTF8.GetBytes(jsonMessage);
            var buffer = new ArraySegment<byte>(bytes);
            await client.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);

            Console.WriteLine("Message sent: " + jsonMessage);
            Boolean isLoggedIn = false;
            var receiveBuffer = new byte[1024000]; // Increased buffer size
            while (client.State == WebSocketState.Open)
            {
                try
                {
                    WebSocketReceiveResult result = await client.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
                    var responseMessage = Encoding.UTF8.GetString(receiveBuffer, 0, result.Count);
                    Console.WriteLine("Message received: " + responseMessage);

                    dynamic jsonResponse = JsonConvert.DeserializeObject(responseMessage);
                    if(!isLoggedIn)
                    {
                        isLoggedIn = true;
                        continue;
                    }
                    string receivedUsername = jsonResponse.username != null ? System.Security.SecurityElement.Escape((string)jsonResponse.username) : "Unknown User";
                    string message = jsonResponse.message != null ? System.Security.SecurityElement.Escape((string)jsonResponse.message) : "No message provided";

                    if (receivedUsername != username)
                    {
                        string command = $"notify-send '{receivedUsername}' '{message}'";
                        await ExecuteCommand(command);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error processing message: " + ex.Message);
                }
            }
        }
    }

    private static async Task ExecuteCommand(string command)
    {
        using (var process = new Process())
        {
            process.StartInfo.FileName = "bash";
            process.StartInfo.Arguments = "-c \"" + command + "\"";
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
            await process.WaitForExitAsync();
        }
    }
}