with Ada.Calendar, Ada.Characters.Latin_1, Ada.Strings.Fixed, Ada.Text_IO;

with GNAT.Sockets;

with Zero_Filled_Image;

procedure Time_Server is
   Address : GNAT.Sockets.Sock_Addr_Type;
   Server  : GNAT.Sockets.Socket_Type;
   Socket  : GNAT.Sockets.Socket_Type;
   Channel : GNAT.Sockets.Stream_Access;
begin
   Address := (Family => GNAT.Sockets.Family_Inet,
               Addr   => GNAT.Sockets.Any_Inet_Addr,
               Port   => 13_000);

   GNAT.Sockets.Create_Socket (Server);
   GNAT.Sockets.Set_Socket_Option (Server,
                                   GNAT.Sockets.Socket_Level,
                                   (GNAT.Sockets.Reuse_Address, True));
   GNAT.Sockets.Bind_Socket (Server, Address);
   GNAT.Sockets.Listen_Socket (Server);
   loop
      GNAT.Sockets.Accept_Socket (Server, Socket, Address);
      Ada.Text_IO.Put_Line ("Wow! Got a call!");
      Channel := GNAT.Sockets.Stream (Socket);

      declare
         function Hours_And_Minutes (S : Duration) return String is
            function Two_Digits is new Zero_Filled_Image (Num   => Natural,
                                                          Width => 2);
            Hours   : Natural := Natural (S) / 3600;
            Minutes : Natural := (Natural (S) - Hours * 3600) / 60;
         begin
            return Two_Digits (Hours) & ":" & Two_Digits (Minutes);
         end Hours_And_Minutes;

         package Latin_1 renames Ada.Characters.Latin_1;
      begin
         String'Write (Channel,
                       "The time here is " &
                       Hours_And_Minutes (Ada.Calendar.Seconds
                                          (Ada.Calendar.Clock)) &
                       "." & Latin_1.LF);
      exception
         when GNAT.Sockets.Socket_Error =>
            null;
         when others =>
            raise;
      end;

      GNAT.Sockets.Close_Socket (Socket);
   end loop;
end Time_Server;

