// See https://aka.ms/new-console-template for more information
using Example;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;

class TestSrvimpl : Example.TestServiceServer<int>
{
   public TestSrvimpl() : base() { }
   public override async Task<Example.AddValueResponse> AddValuesSingleParam(AddValueRequest request, int ctx)
   {
      var res = new Example.AddValueResponse();
      res.value = 1;
      return res;
   }

   public override async Task<double> AddValuesMultipleParams(double value1, double value2, int ctx)
   {
      return value1 + value2;
   }

   public override async Task ReturningVoid(double param1, int ctx)
   {

   }

   public override void OnEvent(string param1, int ctx)
   {
      Console.WriteLine($"OnEvent {param1}");
   }

   public override async Task<IList<double>> FunctionWithArrayAsParamAndReturn(List<double> values1, List<double> values2, int ctx)
   {
      var l = new List<double>();
      l.Append(1);
      return l;
   }

   public override async Task ThrowingError(int ctx)
   {
      throw new Exception("This is a remote error :)");
   }

   public override Task<double> FunctionWithKeywords(double type, double static_, double event_, int ctx)
   {
      throw new NotImplementedException();
   }
}

class CopyTransportS2 : Example.JRpcTransport
{
   CopyTransportS1 tr1;
   public Queue<string> backlog = new Queue<string>();

   public CopyTransportS2(CopyTransportS1 tr1)
   {
      this.tr1 = tr1;
   }

   public override Task Write(string data)
   {
      Console.WriteLine("--> " + data);
      this.tr1.SendPacketEvent(data);

      return Task.CompletedTask;
   }
}

class CopyTransportS1 : Example.JRpcTransport
{
   public Queue<string> backlog = new Queue<string>();

   public CopyTransportS2 tr2;

   public CopyTransportS1()
   {
      this.tr2 = new CopyTransportS2(this);
   }

   public override Task Write(string data)
   {
      Console.WriteLine("<-- " + data);
      this.tr2.SendPacketEvent(data);
      return Task.CompletedTask;
   }
}

class Program
{
   public static void Main()
   {
      Program.Start().Wait();
   }

   public static async Task Start()
   {
      var server = new Example.JRpcServer<int>();
      server.AddService(new TestSrvimpl());
      var transport = new CopyTransportS1();
      var sess = server.GetSession(transport, 0);

      var client = new Example.JRpcClient(transport.tr2);
      var testService = new Example.TestServiceClient(client);

      var result = await testService.AddValuesMultipleParams(1, 2);

      Console.WriteLine($"Add 1 + 2 = {result}");

      try
      {
         await testService.ThrowingError();
         throw new Exception("No error was issued, even though it was expected!");
      }
      catch (JRpcException err)
      {
         Console.WriteLine("Error successfully catched: ", err.Message);
      }
   }
}



