-------------------------------------------------------------------------------
-- (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 SPARK_IO;
with SparkMakeDebug;
with SystemErrors;

package body SparkMakeErrors is

   subtype Error is Fault range Fault'First .. Cannot_Close_File;
   subtype Warning is Fault range Fault'Succ (Error'Last) .. Fault'Last;

   procedure Report
     (The_Fault : in Fault;
      E_Str1    : in E_Strings.T;
      E_Str2    : in E_Strings.T;
      E_Str3    : in E_Strings.T)
   is
   begin
      case The_Fault is

         when Error =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "!!! Sparkmake error: ", 0);

         when Warning =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, ">>> Sparkmake warning: ", 0);
      end case;

      case The_Fault is

         -- COMMAND LINE FAULTS

         when Invalid_Switch =>
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str1);
            SPARK_IO.Put_Line (SPARK_IO.Standard_Output, " is not a recognised switch", 0);

         when Invalid_Argument =>
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str1);
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, " is not a valid argument for switch ", 0);
            E_Strings.Put_Line (File  => SPARK_IO.Standard_Output,
                                E_Str => E_Str2);

         when Duplicate_Switch =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "The switch ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str1);
            SPARK_IO.Put_Line (SPARK_IO.Standard_Output, " cannot be duplicated", 0);

         when Cannot_Find_File =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "Could not find the file ", 0);
            E_Strings.Put_Line (File  => SPARK_IO.Standard_Output,
                                E_Str => E_Str1);

            -- INDEX FILE FAULTS

         when Duplicate_Errors =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "Unit ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str1);
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, " is duplicated in files ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str2);
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, " and ", 0);
            E_Strings.Put_Line (File  => SPARK_IO.Standard_Output,
                                E_Str => E_Str3);

         when Duplicate_Okay =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "Unit ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str1);
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, " in file ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str2);
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, " is already seen in ", 0);
            E_Strings.Put_Line (File  => SPARK_IO.Standard_Output,
                                E_Str => E_Str3);

         when Invalid_Unit =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "File ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str1);
            SPARK_IO.Put_Line (SPARK_IO.Standard_Output, " does not contain a valid unit", 0);

         when Multiple_Main_Programs =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "Files ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str1);
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, " and ", 0);
            E_Strings.Put_String (File  => SPARK_IO.Standard_Output,
                                  E_Str => E_Str2);
            SPARK_IO.Put_Line (SPARK_IO.Standard_Output, " both contain main programs", 0);

            -- GENERAL FILE HANDLING FAULTS
         when Cannot_Open_File =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "Cannot open ", 0);
            E_Strings.Put_Line (File  => SPARK_IO.Standard_Output,
                                E_Str => E_Str1);

         when Cannot_Close_File =>
            SPARK_IO.Put_String (SPARK_IO.Standard_Output, "Cannot close ", 0);
            E_Strings.Put_Line (File  => SPARK_IO.Standard_Output,
                                E_Str => E_Str1);
      end case;
   end Report;

   procedure Fatal (Text : in String) is
      --# hide Fatal;
   begin
      SparkMakeDebug.Report_Text (Text => "Fatal error: " & Text);
      SystemErrors.Fatal_Error (Sys_Err => SystemErrors.Other_Internal_Error,
                                Msg     => "Internal error. ");
   end Fatal;

end SparkMakeErrors;
