-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

with Ada.Streams.Stream_IO;

with GNAT.OS_Lib;
with GNAT.Table;

package Work_Manager is
   type AnalysisType is (Simplify,
                         Zombiescope,
                         --  Jobs below here do not produce a log file when "-l" is specified.
                         Victor,
                         Riposte);

   subtype Logless_Job is AnalysisType range Victor .. Riposte;

   MaxErrorStringIndex : constant Integer := 100;
   subtype ErrorStringIndex is Integer range 1 .. MaxErrorStringIndex;
   subtype ErrorString is String (ErrorStringIndex);

   NullErrorString : constant ErrorString := ErrorString'(others => ' ');

   subtype Job_Index is Natural;
   subtype Worker_ID is Natural;

   AnyFailed : Boolean := False;

   --  Keep track of the status of jobs in the list.
   --  At present this is not really used for anything, but it could be
   --  useful info if we add a monitor thread at a later date.
   type JobStatus is (Pending, InProgress, Finished, Failed);

   --  Record for details of each job.
   type Work_Package is record
      File_Name : GNAT.OS_Lib.String_Access;
      File_Size : Ada.Streams.Stream_IO.Count;
      Analysis  : AnalysisType;
      Status    : JobStatus := Pending;
      Worker    : Worker_ID := 0;
      WhyFailed : ErrorString;
   end record;

   --  Work_List manages the list of jobs to be done.
   package Jobs is
      procedure Add_Work_Package (File    : in String;
                                  JobType : in AnalysisType);
      procedure GetNextJob (Job_ID : out Job_Index);
      procedure JobFinished (Job : in Job_Index);
      procedure JobFailed (Job        : in Job_Index;
                           FailReason : in ErrorString);
      procedure Sort_Files_By_Size;
      procedure Display_Status_Banner;
      function Total_Number_Of_Files return Job_Index;
      function Number_Of_Files (Of_Status : in JobStatus) return Job_Index;
      procedure List_Jobs;
      function Get_File_Name (Job : in Job_Index) return String;
      function Get_Simple_File_Name (Job : in Job_Index) return String;
      function Get_Analysis_Type (Job : in Job_Index) return AnalysisType;
      function Get_HasFailed (Job : in Job_Index) return Boolean;
      function Get_WhyFailed (Job : in Job_Index) return ErrorString;
      procedure Clear;
   end Jobs;

private

   package Work_Table is new GNAT.Table (
                                         Table_Component_Type => Work_Package,
                                         Table_Index_Type => Job_Index,
                                         Table_Low_Bound => 1,
                                         Table_Initial => 1000,
                                         Table_Increment => 100);

end Work_Manager;
