using System.Net.Sockets; using System.Text; using System.Text.Json; using System.Collections.Concurrent; namespace Library; public class Server { private TcpClient client; private NetworkStream stream; private StreamReader reader; private StreamWriter writer; private Action onMessageReceived; private ConcurrentDictionary> pendingRequests = new(); public Server(string ip, int port) { ConnectAsync(ip, port).Wait(); } private async Task ConnectAsync(string serverIp, int serverPort) { client = new TcpClient(); await client.ConnectAsync(serverIp, serverPort); stream = client.GetStream(); reader = new StreamReader(stream, Encoding.UTF8); writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true }; Console.WriteLine("Connected to the server."); _ = ReceiveMessagesAsync(); // Start receiving messages in the background } private async Task ReceiveMessagesAsync() { try { while (client.Connected) { string message = await reader.ReadLineAsync(); if (message != null) { // Parse the JSON response var response = JsonSerializer.Deserialize(message); if (response != null && pendingRequests.TryRemove(response.Id, out var tcs)) { tcs.SetResult(response.Response); // Complete the task with the response } else { onMessageReceived?.Invoke(message); // Handle other messages } } } } catch (Exception ex) { Console.WriteLine("Error receiving data: " + ex.Message); } } private async Task ExecuteCommandAsync(string command) { var requestId = Guid.NewGuid().ToString(); // Generate a unique ID for the request var tcs = new TaskCompletionSource(); pendingRequests[requestId] = tcs; // Create the JSON request var request = new JsonRequest { Id = requestId, Command = command }; string jsonString = JsonSerializer.Serialize(request); // Send the command with the request ID await SendMessageAsync(jsonString); // Await the response return await tcs.Task; } private async Task SendMessageAsync(string message) { if (client.Connected) { await writer.WriteLineAsync(message); } } private class JsonRequest { public string Id { get; set; } public string Command { get; set; } } private class JsonResponse { public string Id { get; set; } public string Response { get; set; } } public Task GetEmployee(int? id = null, string code = null) { if (id == null && code == null) { throw new ArgumentException("Either id or code must be provided."); } if (id != null && code != null) { throw new ArgumentException("Only one of id or code should be provided."); } Employee? employee = null; string commandResult; // Implement logic to get a worker by ID or code if (id != null) commandResult = ExecuteCommandAsync(".get worker byid " + id).Result; else commandResult = ExecuteCommandAsync(".get worker bycode " + id).Result; // Deserialize the command result to an Employee object try { employee = JsonSerializer.Deserialize(commandResult); return Task.FromResult(employee); } catch (JsonException) { Console.WriteLine("Failed to deserialize the command result."); } return Task.FromException(new Exception("Failed to get worker.")); } public Task Login(string username, string password) { // Implement login logic var commandResult = ExecuteCommandAsync(".login " + username + " " + password).Result; if (commandResult == "success") { return Task.FromResult("Success"); } return Task.FromException(new Exception("Failed to login.")); } public Task Logout() { // Implement logout logic var commandResult = ExecuteCommandAsync(".logout").Result; if (commandResult == "success") { return Task.FromResult("Success"); } return Task.FromException(new Exception("Failed to logout.")); } public Task clockIn(Employee employee) { var commandResult = ExecuteCommandAsync(".clockin ").Result; if (commandResult == "success") { return Task.FromResult("Success"); } return Task.FromException(new Exception("Failed to clock in.")); } public Task clockOut(Employee employee) { var commandResult = ExecuteCommandAsync(".clockout ").Result; if (commandResult == "success") { return Task.FromResult("Success"); } else { return Task.FromException(new Exception("Failed to clock out.")); } } public Task clockBreak(Employee employee) { var commandResult = ExecuteCommandAsync(".clockbreak").Result; if (commandResult == "success") { return Task.FromResult("Success"); } else { return Task.FromException(new Exception("Failed to clock break.")); } } }