-------------------------------------------------------------------------------
-- (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.
--
--=============================================================================

separate (ErrorHandler.Conversions.ToString)
procedure CondlDependency (Err_Num          : in     Error_Types.NumericError;
                           With_Explanation : in     Boolean;
                           E_Str            : in out E_Strings.T) is
   Err_Type : ErrorHandler.Full_Depend_Err_Type;

   procedure CondlDependencyExpl (E_Str : in out E_Strings.T)
   --# global in Err_Type;
   --# derives E_Str from *,
   --#                    Err_Type;
      is separate;
   -- Note that the parameter names for this subunit are chosen to make it as easy as
   --      possible to auto-generate the subunit from this, its parent, file.  The
   --      generation requires copying the case statement below, stripping out the
   --      current Append'Thing' statements and adding an Append_String for the
   --      explanatory text that is delineated by --! comments.

   procedure Append_Explanation
   --# global in     Err_Type;
   --#        in     With_Explanation;
   --#        in out E_Str;
   --# derives E_Str from *,
   --#                    Err_Type,
   --#                    With_Explanation;
   is
      Explanation_String : E_Strings.T := E_Strings.Empty_String;
   begin
      if With_Explanation then
         -- we need to at least look for an explanation
         CondlDependencyExpl (E_Str => Explanation_String);
         if E_Strings.Get_Length (E_Str => Explanation_String) > 0 then
            -- there actually is one
            E_Strings.Append_String (E_Str => E_Str,
                                     Str   => ErrorHandler.Explanation_Prefix);
            E_Strings.Append_Examiner_String (E_Str1 => E_Str,
                                              E_Str2 => Explanation_String);
            E_Strings.Append_String (E_Str => E_Str,
                                     Str   => ErrorHandler.Explanation_Postfix);
         end if;
      end if;
   end Append_Explanation;

begin
   Err_Type := ErrorHandler.Dependency_Err_Type'Val (Err_Num.ErrorNum - Error_Types.CondDependencyErrorOffset);
   case Err_Type is

      -- HTML Directives
      --! <NameFormat> <"flow-"><Name>
      --! <ErrorFormat> <"??? Flow Error : "><Name><" : "><Error>

      when ErrorHandler.May_Be_Used_New =>
         --! <Name> 601
         Append_Export_Var (E_Str, Err_Num.Name2, Err_Num.Scope, True);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " may be derived from the imported value(s) of ");
         Append_Export_Var (E_Str, Err_Num.Name1, Err_Num.Scope, False);
         --! Here the item on the left of &quot;may be derived from ...&quot; is an exported variable and
         --! the item(s) on the right are imports of a procedure subprogram.
         --! The message reports a possible dependency, found in the code, which
         --! does not appear in the specified dependency relation (derives annotation).
         --! The discrepancy could be caused by an error in the subprogram code which implements
         --! an unintended dependency.  It could also be in an error in the subprogram derives annotation
         --! which omits a necessary and intended dependency.  Finally, the Examiner may be reporting
         --! a false coupling between two items resulting from a non-executable code path or the
         --! sharing of disjoint parts of structured or abstract data (e.g one variable writing to one element
         --! of an array and another variable reading back a different element).
         --! Unexpected dependencies should be investigated carefully and only accepted without modification
         --! of either code or annotation if it is certain they are of &quot;false coupling&quot; kind.

      when ErrorHandler.May_Be_Used =>  -- Legacy

         --! <Name> 601
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "The imported value of ");
         Append_Name (E_Str => E_Str,
                      Name  => Err_Num.Name1,
                      Scope => Err_Num.Scope);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " may be used in the derivation of ");
         Append_Export_Var (E_Str, Err_Num.Name2, Err_Num.Scope, False);
         --! Here first item is an import and the second is an export of a procedure subprogram.
         --! The message reports a possible dependency, found in the code, which
         --! does not appear in the specified dependency relation.
         --! This version of the message has been retained for backward compatibility.

      when ErrorHandler.May_Be_Used_Continue =>
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => ", ");
         Append_Name (E_Str => E_Str,
                      Name  => Err_Num.Name1,
                      Scope => Err_Num.Scope);

      when ErrorHandler.Uninitialised =>
         --! <Name> 602
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "The undefined initial value of ");
         Append_Name (E_Str => E_Str,
                      Name  => Err_Num.Name1,
                      Scope => Err_Num.Scope);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " may be used in the derivation of ");
         Append_Export_Var (E_Str, Err_Num.Name2, Err_Num.Scope, False);
         --! Here XXX is a non-imported variable, and YYY is an export, of a
         --! procedure subprogram.

      when ErrorHandler.Integrity_Violation =>
         --! <Name> 605
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "Information flow from ");
         Append_Name (E_Str => E_Str,
                      Name  => Err_Num.Name1,
                      Scope => Err_Num.Scope);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " to ");
         Append_Export_Var (E_Str, Err_Num.Name2, Err_Num.Scope, False);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " violates information flow policy");
         --! This message indicates a violation of security or safety policy, such
         --! as information flow from a Secret input to an Unclassified output.

      when ErrorHandler.May_Be_Integrity_Violation =>
         --! <Name> 606
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "The imported value of ");
         Append_Name (E_Str => E_Str,
                      Name  => Err_Num.Name1,
                      Scope => Err_Num.Scope);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " may be used in the derivation of ");
         Append_Export_Var (E_Str, Err_Num.Name2, Err_Num.Scope, False);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => ". Furthermore, this information flow violates ");
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "information flow policy.");
         --! Here XXX is an import and YYY is an export of a procedure subprogram.
         --! The message reports a possible dependency, found in the code, which
         --! does not appear in the specified dependency relation. If this dependency
         --! did appear in the dependency relation, then it would also constitute
         --! an integrity violation.

      when others =>
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "UNKNOWN ERROR NUMBER PASSED TO Condl_Dependency");
   end case;
   Append_Explanation;
   if Err_Type /= ErrorHandler.May_Be_Used_Continue and Err_Type /= ErrorHandler.May_Be_Used_New then
      E_Strings.Append_String (E_Str => E_Str,
                               Str   => ".");
   end if;
end CondlDependency;
