with GNAT.Strings;
with GNATCOLL.Projects;          use GNATCOLL.Projects;
with GNATCOLL.VFS;               use GNATCOLL.VFS;
with GNATCOLL.Traces;            use GNATCOLL.Traces;
with GNATCOLL.VFS_Utils;         use GNATCOLL.VFS_Utils;

with Ada.Containers.Indefinite_Ordered_Sets;
with Ada.Containers.Indefinite_Vectors;

with Ada.Text_IO;

with GNAT.OS_Lib;             use GNAT.OS_Lib;
with Ada.Characters.Handling; use Ada.Characters.Handling;

procedure Main is
   Env                 : Project_Environment_Access;
   Source_Project_Tree : GNATCOLL.Projects.Project_Tree;

   P : Project_Type;

   package String_Set is new Ada.Containers.Indefinite_Ordered_Sets (String);
   use String_Set;

   Paths         : String_Set.Set;

   procedure Has_Elem (Paths : String_Set.Set; Elem : String; Msg : String);
   procedure Has_Elem (Paths : String_Set.Set; Elem : String; Msg : String) is
   begin
      if Paths.Find (Elem) = String_Set.No_Element then
         Ada.Text_IO.Put_Line (Elem & Msg);
      end if;
   end Has_Elem;

   procedure Check_Info
     (File_Name    : String;
      Info_Elem    : File_Info;
      Project_Name : String;
      Unit_Part    : Unit_Parts;
      Unit_Name    : String;
      Language     : String);
   procedure Check_Info
     (File_Name    : String;
      Info_Elem    : File_Info;
      Project_Name : String;
      Unit_Part    : Unit_Parts;
      Unit_Name    : String;
      Language     : String) is
   begin
      if To_Lower (Info_Elem.Project.Name) /= To_Lower (Project_Name) then
         Ada.Text_IO.Put_Line
           ("wrong project for " & File_Name
            & ": " & To_Lower (Info_Elem.Project.Name)
            & " instead of " & To_Lower (Project_Name));
      end if;
      if Info_Elem.Language /= Language then
         Ada.Text_IO.Put_Line
           ("wrong language for " & File_Name
            & ": " & Info_Elem.Language & " instead of " & Language);
      end if;
      if Info_Elem.Unit_Part /= Unit_Part then
         Ada.Text_IO.Put_Line
           ("wrong unit part for " & File_Name
            & ": " & Unit_Parts'Image (Info_Elem.Unit_Part) &
              " instead of "  & Unit_Parts'Image (Unit_Part));
      end if;
      if Info_Elem.Unit_Name /= Unit_Name then
         Ada.Text_IO.Put_Line
           ("wrong unit name for " & File_Name
            & ": " & Info_Elem.Unit_Name & " instead of " & Unit_Name);
      end if;
   end Check_Info;


   Cur_Dir : constant Virtual_File := Get_Current_Dir;

   Str : String_Access;
begin
   Parse_Config_File;
   Set_Active (Create ("Projects.Aggregate"), True);
--     Set_Active (Create ("Projects"), True);
   Initialize (Env);
   Env.Register_Default_Language_Extension ("C", ".h", ".c");
   Env.Set_Path_From_Gnatls ("gnatls", Str);
   Free (Str);
   Source_Project_Tree.Load (GNATCOLL.VFS.Create (+"aggr.gpr"), Env);

   if Source_Project_Tree.Root_Project = No_Project then
      Ada.Text_IO.Put_Line ("project not loaded");
   end if;


   declare

      Source_Name_W : constant String :=
        "C2" & Directory_Separator & "SrC_c2"
        & Directory_Separator & "sHaReD_sRc.ads";
      --  Windows specific, mixed casing.

      use File_Info_Sets;

      Infoset   : File_Info_Set;
      Info_Elem : File_Info;

   begin
      Infoset := Info_Set
        (Source_Project_Tree, Create (Normalize_Pathname (+Source_Name_W)));
      if Integer (Infoset.Length) /= 2 then
         Ada.Text_IO.Put_Line
           ("wrong number of info for " & Source_Name_W);
      else
         Info_Elem := File_Info (Infoset.First_Element);

         Check_Info
           (Source_Name_W,
            Info_Elem,
            "c",
            Unit_Spec,
            "shared_src",
            "ada");

         Paths.Include
           (+Relative_Path (Info_Elem.Project.Project_Path, Cur_Dir));

         Info_Elem := File_Info (Infoset.Last_Element);

         Check_Info
           (Source_Name_W,
            Info_Elem,
            "c",
            Unit_Spec,
            "shared_src",
            "ada");

         Paths.Include
           (+Relative_Path (Info_Elem.Project.Project_Path, Cur_Dir));

         Has_Elem
           (Paths,
            "c1" & Directory_Separator & "c.gpr",
            " missed in info for shared_src.ads");
         Has_Elem
           (Paths,
            "c2" & Directory_Separator & "c.gpr",
            " missed in info for shared_src.ads");

         Paths.Clear;
      end if;

   end;

   Source_Project_Tree.Unload;
   Free (Env);
end Main;
