using System.Net;
using System.Net.Sockets;
using System.Text;
using GatewaySCO;

namespace gatewayPruebasECO_POSBC;

// Activa servidor para pruebas, acepta mensajes que retorna identicos.
public class SocketServer
{
    private const int Port = 6698; // Puerto en el que el servidor escuchará

    public static void Main()
    {
        Socket? listener = null;
        try
        {
            // Crear un socket de escucha
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listener.Bind(new IPEndPoint(IPAddress.Any, Port));
            listener.Listen(10);
            Console.WriteLine($"Servidor #1 ECO_POSBC escuchando en el puerto {Port}...");

            // Aceptar una conexión de cliente
            using Socket clientSocket = listener.Accept();
            Console.WriteLine("Cliente conectado.");
            while (true)
            {
                Console.WriteLine("..esperando mensaje.");
                // Recibir el mensaje del cliente
                byte[] buffer = new byte[4096];
                int bytesRead = clientSocket.Receive(buffer);
                string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                Console.WriteLine($"Mensaje recibido: {message}");

                // Enviar el mismo mensaje de vuelta al cliente
                clientSocket.Send(buffer, bytesRead, SocketFlags.None);
                Console.WriteLine("Mensaje enviado de vuelta al cliente.");

                // Enviar mensajes aleatorios adicionales
                Random random = new Random();
                int additionalMessages = random.Next(0, 6); // Número aleatorio entre 0 y 5

                for (int i = 1; i <= additionalMessages; i++)
                {
                    int delay = random.Next(100, 5001); // Tiempo de espera aleatorio entre 0.1 y 5 segundos
                    Task.Delay(delay).Wait(); // Espera asincrónica

                    string additionalMessage = $"mensaje aleatorio {i} después de {delay}ms";
                    byte[] additionalData = Util.ConvierteEnBufferBytes(additionalMessage);
                    clientSocket.Send(additionalData, SocketFlags.None);
                    Console.WriteLine($"Mensaje adicional enviado: {additionalMessage}");
                    Console.WriteLine(Util.DetalleMensajes(additionalData));
                }
            }
        }
        catch (SocketException e)
        {
            Console.WriteLine($"Error de socket: {e.Message}");
        }
        finally
        {
            // Cerrar el socket de escucha
            listener?.Close();
        }
    }
}



// using System;
// using System.Net;
// using System.Net.Sockets;
// using System.Text;
// using System.Threading.Tasks;

// public class SocketServer
// {
//     private const int Port = 6698; // Puerto en el que el servidor escuchará
//     private static readonly Random Random = new Random();

//     public static async Task Main()
//     {
//         Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//         listener.Bind(new IPEndPoint(IPAddress.Any, Port));
//         listener.Listen(10);
//         Console.WriteLine($"POSBC #4 Servidor escuchando en el puerto {Port}...");

//         while (true)
//         {
//             Socket clientSocket = await listener.AcceptAsync();
//             _ = Task.Run(() => HandleClientAsync(clientSocket));
//         }
//     }

//     private static async Task HandleClientAsync(Socket clientSocket)
//     {
//         while (true)
//         {
//             // Leer los primeros 4 bytes para obtener la longitud del mensaje
//             byte[] bufferCabecera = new byte[4];
//             int bytesRead = await clientSocket.ReceiveAsync(new ArraySegment<byte>(bufferCabecera), SocketFlags.None);
//             if (bytesRead == 0) break; // La conexión se ha cerrado
//             uint longitudMsj = Util.LongitudMensaje(bufferCabecera);

//             byte[] bufferMensaje = new byte[longitudMsj];

//             // Leer el mensaje completo basado en la longitud
//             bytesRead = await clientSocket.ReceiveAsync(new ArraySegment<byte>(bufferMensaje), SocketFlags.None);
//             if (bytesRead == 0) break; // La conexión se ha cerrado

//             string message = Encoding.UTF8.GetString(bufferMensaje);
//             Console.WriteLine($"Mensaje recibido: >{message}< longitud en cabecera {longitudMsj}, longitud del texto {message.Length}");

//             // Enviar el mismo mensaje de vuelta al clientA
//             bufferMensaje = Util.ConvierteEnBufferBytes(message);
//             await clientSocket.SendAsync(new ArraySegment<byte>(bufferMensaje), SocketFlags.None);
//             Console.WriteLine("Mensaje enviado de vuelta al cliente >{msj}<", message);
//             //await EnviarMensaje(clientSocket, message);

//             // Enviar de 0 a 3 mensajes adicionales
//             int additionalMessages = Random.Next(0, 4);
//             Console.WriteLine("Número mensajes aleatorioes de respuesta {n}", additionalMessages);
//             for (int i = 1; i <= additionalMessages; i++)
//             {
//                 int delay = Random.Next(100, 3001);
//                 await Task.Delay(delay);

//                 string additionalMessage = $"{message} - Mensaje aleatorio {i} - generado POSBC";
//                 bufferMensaje = Util.ConvierteEnBufferBytes(additionalMessage);

//                 await clientSocket.SendAsync(new ArraySegment<byte>(bufferMensaje), SocketFlags.None);
//                 Console.WriteLine($"Mensaje adicional enviado: {additionalMessage}");
//             }
//         }

//         clientSocket.Close();
//     }

// }

