--
--  Copyright (C) 2022-2023, AdaCore
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
--

--  LAL_Refactor scope_declarations tool

with Libadalang.Analysis;
with Ada.Containers.Indefinite_Ordered_Maps;
with Ada.Containers.Indefinite_Ordered_Sets;
with GNATCOLL.Opt_Parse; use GNATCOLL.Opt_Parse;
with VSS.Text_Streams;

package LAL_Refactor.Tools.Scope_Declarations_Tool is
   package LAL renames Libadalang.Analysis;
   package ReFac renames LAL_Refactor;
   Parser : Argument_Parser :=
     Create_Argument_Parser (Help => "Suppress Params");

   function "<" (L, R : LAL.Ada_Node) return Boolean;
   function "<" (L, R : LAL.Defining_Name) return Boolean
   is (L.As_Ada_Node < R.As_Ada_Node);
   function "<" (L, R : LAL.Object_Decl) return Boolean
   is (L.As_Ada_Node < R.As_Ada_Node);
   function "<" (L, R : LAL.Declarative_Part) return Boolean
   is (L.As_Ada_Node < R.As_Ada_Node);

   package Obj_Decl_To_Edit_Map is
     new Ada.Containers.Indefinite_Ordered_Maps
       (Key_Type            => LAL.Object_Decl,
        Element_Type        => ReFac.Text_Edit_Map,
        "<"                 => "<",
        "="                 => ReFac.Text_Edit_Ordered_Maps."=");

   package Decl_Part_To_Edit_Map is
     new Ada.Containers.Indefinite_Ordered_Maps
       (Key_Type            => LAL.Declarative_Part,
        Element_Type        => ReFac.Text_Edit_Map,
        "<"                 => "<",
        "="                 => ReFac.Text_Edit_Ordered_Maps."=");

   package Defining_Name_Ordered_Sets is
     new Ada.Containers.Indefinite_Ordered_Sets
       (Element_Type => LAL.Defining_Name,
        "<"          => "<",
        "="          => LAL."=");

   package Obj_Decl_To_Defining_Name is
      new Ada.Containers.Indefinite_Ordered_Maps
       (Key_Type            => LAL.Object_Decl,
        Element_Type        => Defining_Name_Ordered_Sets.Set,
        "<"                 => "<",
        "="                 => Defining_Name_Ordered_Sets."=");

   type Modify_Info is record
      Object_To_Decl : Obj_Decl_To_Defining_Name.Map;
      Edit_Info : Obj_Decl_To_Edit_Map.Map;
      Removable_Decl_Part : Decl_Part_To_Edit_Map.Map;
   end record;

   function Scope_Declarations (Unit_Array : LAL.Analysis_Unit_Array)
                                return Modify_Info;

   procedure Run (Unit_Array : LAL.Analysis_Unit_Array;
                  Stream     : in out
                    VSS.Text_Streams.Output_Text_Stream'Class);

   function Interact return ReFac.Text_Edit_Map;

end LAL_Refactor.Tools.Scope_Declarations_Tool;
