with Ada.Command_Line, Ada.Streams;

with EUP.Sockets, EUP.Text_IO, GNAT.Sockets, Stream_Shortcuts;

procedure Replying_Datagram_Receiver is
   procedure Reply_To_Sender (Socket : in     GNAT.Sockets.Socket_Type;
                              Answer : in     String;
                              Sender : in     GNAT.Sockets.Sock_Addr_Type) is
      Last : Ada.Streams.Stream_Element_Offset;
   begin
      GNAT.Sockets.Send_Socket (Socket => Socket,
                                Item   => Stream_Shortcuts.To_Stream (Answer),
                                Last   => Last,
                                To     => Sender);
   end Reply_To_Sender;

   use type Ada.Streams.Stream_Element_Offset;

   Port    : GNAT.Sockets.Port_Type;
   Socket  : GNAT.Sockets.Socket_Type;
   Buffer  : Ada.Streams.Stream_Element_Array (1 .. 1024);
   Last    : Ada.Streams.Stream_Element_Offset;
   Address : GNAT.Sockets.Sock_Addr_Type;
begin
   begin
      Port := GNAT.Sockets.Port_Type'Value (Ada.Command_Line.Argument (1));
   exception
      when others =>
         EUP.Text_IO.Put_Line (File => EUP.Text_IO.Standard_Error,
                               Item => "usage: " &
                                       Ada.Command_Line.Command_Name &
                                       " port_number");
         Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
         return;
   end;

   Socket := EUP.Sockets.Make_Server (Port => Port,
                                      Mode => GNAT.Sockets.Socket_Datagram);

   loop
      GNAT.Sockets.Receive_Socket (Socket => Socket,
                                   Item   => Buffer,
                                   Last   => Last,
                                   From   => Address);
      exit when Last < Buffer'First;

      EUP.Text_IO.Put_Line
        (File => EUP.Text_IO.Standard_Output,
         Item => "dgrecv: got a message: " &
                 Stream_Shortcuts.To_String (Buffer (Buffer'First .. Last)));
      EUP.Text_IO.Put_Line
        (File => EUP.Text_IO.Standard_Output,
         Item => "  from: " & GNAT.Sockets.Image (Address));
      Reply_To_Sender
        (Socket => Socket,
         Answer => "Thanks for your " &
                   Ada.Streams.Stream_Element_Offset'Image (Last) &
                   " char message.",
         Sender => Address);
   end loop;
end Replying_Datagram_Receiver;

