------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                    G N A T . S O C K E T S . P O L L                     --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                       Copyright (C) 2020-2021, AdaCore                   --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Calendar;

with GNAT.Sockets.Thin;

package body GNAT.Sockets.Poll is

   To_C : constant array (Wait_Event_Type) of Events_Type :=
            (Input => SOC.POLLIN or SOC.POLLPRI, Output => SOC.POLLOUT);
   --  To convert Wait_Event_Type to C I/O events flags

   procedure Set_Mode (Item : out Pollfd; Mode : Wait_Event_Set);
   --  Set I/O waiting mode on Item

   procedure Set_Event
     (Item : out Pollfd; Event : Wait_Event_Type; Value : Boolean);
   --  Set or reset waiting state on I/O event

   procedure Check_Range (Self : Set; Index : Positive) with Inline;
   --  raise Constraint_Error if Index is more than number of sockets in Self

   function Status (Item : Pollfd) return Event_Set is
     (Input           => (Item.REvents and To_C (Input)) /= 0,
      Output          => (Item.REvents and To_C (Output)) /= 0,
      Error           => (Item.REvents and SOC.POLLERR) /= 0,
      Hang_Up         => (Item.REvents and SOC.POLLHUP) /= 0,
      Invalid_Request => (Item.REvents and SOC.POLLNVAL) /= 0);
   --  Get I/O events from C word

   procedure Wait
     (Fds : in out Set; Timeout : Interfaces.C.int; Result : out Integer);
   --  Waits until one or more of the sockets descriptors become ready for some
   --  class of I/O operation or error state occurs on one or more of them.
   --  Timeout is in milliseconds. Result mean how many sockets ready for I/O
   --  or have error state.

   ----------
   -- Wait --
   ----------

   procedure Wait
     (Fds : in out Set; Timeout : Interfaces.C.int; Result : out Integer)
   is separate;

   ------------
   -- Create --
   ------------

   function Create (Size : Positive) return Set is
   begin
      return Result : Set (Size);
   end Create;

   ------------
   -- To_Set --
   ------------

   function To_Set
     (Socket : Socket_Type;
      Events : Wait_Event_Set;
      Size   : Positive := 1) return Set is
   begin
      return Result : Set (Size) do
         Append (Result, Socket, Events);
      end return;
   end To_Set;

   ------------
   -- Append --
   ------------

   procedure Append
     (Self : in out Set; Socket : Socket_Type; Events : Wait_Event_Set) is
   begin
      Insert (Self, Socket, Events, Self.Length + 1);
   end Append;

   ------------
   -- Insert --
   ------------

   procedure Insert
     (Self       : in out Set;
      Socket     : Socket_Type;
      Events     : Wait_Event_Set;
      Index      : Positive;
      Keep_Order : Boolean := False) is
   begin
      if Self.Size <= Self.Length then
         raise Constraint_Error with "Socket set is full";

      elsif Index > Self.Length + 1 then
         raise Constraint_Error with "Insert out of range";
      end if;

      if Socket < 0 then
         raise Socket_Error with
           "Wrong socket descriptor " & Socket_Type'Image (Socket);
      end if;

      Self.Length := Self.Length + 1;

      if Index /= Self.Length then
         if Keep_Order then
            Self.Fds (Index + 1 .. Self.Length) :=
              Self.Fds (Index .. Self.Length - 1);
         else
            Self.Fds (Self.Length) := Self.Fds (Index);
         end if;

         Self.Fds (Index).Events := 0;
      end if;

      Self.Fds (Index).Socket := FD_Type (Socket);
      Set_Mode (Self.Fds (Index), Events);

      if FD_Type (Socket) > Self.Max_FD then
         Self.Max_FD := FD_Type (Socket);
         Self.Max_OK := True;
      end if;
   end Insert;

   -----------------
   -- Check_Range --
   -----------------

   procedure Check_Range (Self : Set; Index : Positive) is
   begin
      if Index > Self.Length then
         raise Constraint_Error;
      end if;
   end Check_Range;

   ----------
   -- Copy --
   ----------

   procedure Copy (Source : Set; Target : out Set) is
   begin
      if Target.Size < Source.Length then
         raise Constraint_Error with
           "Can't copy because size of target less than source length";
      end if;

      Target.Fds (1 .. Source.Length) := Source.Fds (1 .. Source.Length);

      Target.Length := Source.Length;
      Target.Max_FD := Source.Max_FD;
      Target.Max_OK := Source.Max_OK;
   end Copy;

   ----------------
   -- Get_Events --
   ----------------

   function Get_Events
     (Self : Set; Index  : Positive) return Wait_Event_Set is
   begin
      Check_Range (Self, Index);
      return
        (Input  => (Self.Fds (Index).Events and To_C (Input)) /= 0,
         Output => (Self.Fds (Index).Events and To_C (Output)) /= 0);
   end Get_Events;

   ------------
   -- Growth --
   ------------

   function Growth (Self : Set) return Set is
   begin
      return Resize
        (Self,
         (case Self.Size is
             when 1  .. 20 => 32,
             when 21 .. 50 => 64,
             when 51 .. 99 => Self.Size + Self.Size / 3,
             when others   => Self.Size + Self.Size / 4));
   end Growth;

   ------------
   -- Remove --
   ------------

   procedure Remove
     (Self : in out Set; Index : Positive; Keep_Order : Boolean := False) is
   begin
      Check_Range (Self, Index);

      if Self.Max_FD = Self.Fds (Index).Socket then
         Self.Max_OK := False;
      end if;

      if Index < Self.Length then
         if Keep_Order then
            Self.Fds (Index .. Self.Length - 1) :=
              Self.Fds (Index + 1 .. Self.Length);
         else
            Self.Fds (Index) := Self.Fds (Self.Length);
         end if;
      end if;

      Self.Length := Self.Length - 1;
   end Remove;

   ------------
   -- Resize --
   ------------

   function Resize (Self : Set; Size : Positive) return Set is
   begin
      return Result : Set (Size) do
         Copy (Self, Result);
      end return;
   end Resize;

   ---------------
   -- Set_Event --
   ---------------

   procedure Set_Event
     (Self  : in out Set;
      Index : Positive;
      Event : Wait_Event_Type;
      Value : Boolean) is
   begin
      Check_Range (Self, Index);
      Set_Event (Self.Fds (Index), Event, Value);
   end Set_Event;

   procedure Set_Event
     (Item : out Pollfd; Event : Wait_Event_Type; Value : Boolean) is
   begin
      if Value then
         Item.Events := Item.Events or To_C (Event);
      else
         Item.Events := Item.Events and not To_C (Event);
      end if;
   end Set_Event;

   ----------------
   -- Set_Events --
   ----------------

   procedure Set_Events
     (Self   : in out Set;
      Index  : Positive;
      Events : Wait_Event_Set) is
   begin
      Check_Range (Self, Index);
      Set_Mode (Self.Fds (Index), Events);
   end Set_Events;

   --------------
   -- Set_Mode --
   --------------

   procedure Set_Mode (Item : out Pollfd; Mode : Wait_Event_Set) is
   begin
      for J in Mode'Range loop
         Set_Event (Item, J, Mode (J));
      end loop;
   end Set_Mode;

   ------------
   -- Socket --
   ------------

   function Socket (Self : Set; Index : Positive) return Socket_Type is
   begin
      Check_Range (Self, Index);
      return Socket_Type (Self.Fds (Index).Socket);
   end Socket;

   -----------
   -- State --
   -----------

   procedure State
     (Self   : Set;
      Index  : Positive;
      Socket : out Socket_Type;
      Status : out Event_Set) is
   begin
      Check_Range (Self, Index);
      Socket := Socket_Type (Self.Fds (Index).Socket);
      Status := Poll.Status (Self.Fds (Index));
   end State;

   ----------
   -- Wait --
   ----------

   procedure Wait (Self : in out Set; Timeout : Duration; Count : out Natural)
   is
      use Ada.Calendar;
      --  Used to calculate partially consumed timeout on EINTR.
      --  Better to use Ada.Real_Time, but we can't in current GNAT because
      --  Ada.Real_Time is in tasking part of runtime.

      Result       : Integer;
      Poll_Timeout : Duration := Timeout;
      C_Timeout    : Interfaces.C.int;
      Errno        : Integer;
      Stamp        : constant Time := Clock;
   begin
      if Self.Length = 0 then
         Count := 0;
         return;
      end if;

      loop
         if Poll_Timeout >= Duration (Interfaces.C.int'Last - 8) / 1_000 then
            --  Minus 8 is to workaround Linux kernel 2.6.24 bug with close to
            --  Integer'Last poll timeout values.
            --  syscall (SYS_poll, &ufds, 1, 2147483644); // is waiting
            --  syscall (SYS_poll, &ufds, 1, 2147483645); // is not waiting
            --  Timeout values close to maximum could be not safe because of
            --  possible time conversion boundary errors in the kernel.
            --  Use unlimited timeout instead of maximum 24 days timeout for
            --  safety reasons.

            C_Timeout := -1;
         else
            C_Timeout := Interfaces.C.int (Poll_Timeout * 1_000);
         end if;

         Wait (Self, C_Timeout, Result);

         exit when Result >= 0;

         Errno := Thin.Socket_Errno;

         --  In case of EINTR error we have to continue waiting for network
         --  events.

         if Errno = SOC.EINTR then
            if C_Timeout >= 0 then
               Poll_Timeout := Timeout - (Clock - Stamp);

               if Poll_Timeout < 0.0 then
                  Poll_Timeout := 0.0;

               elsif Poll_Timeout > Timeout then
                  --  Clock moved back in time. This should not be happen when
                  --  we use monotonic time.

                  Poll_Timeout := Timeout;
               end if;
            end if;

         else
            Raise_Socket_Error (Errno);
         end if;
      end loop;

      Count := Result;
   end Wait;

   ----------
   -- Next --
   ----------

   procedure Next (Self : Set; Index : in out Natural) is
   begin
      loop
         Index := Index + 1;

         if Index > Self.Length then
            Index := 0;
            return;

         elsif Self.Fds (Index).REvents /= 0 then
            return;
         end if;
      end loop;
   end Next;

   ------------
   -- Status --
   ------------

   function Status (Self : Set; Index : Positive) return Event_Set is
   begin
      Check_Range (Self, Index);
      return Status (Self.Fds (Index));
   end Status;

   --------------
   -- C_Status --
   --------------

   function C_Status
     (Self : Set; Index : Positive) return Interfaces.C.unsigned is
   begin
      Check_Range (Self, Index);
      return Interfaces.C.unsigned (Self.Fds (Index).REvents);
   end C_Status;

end GNAT.Sockets.Poll;
