--------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Gnostic is Ada Generic Neural Object System Engineering.                                                                                                --
-- Gnostic (C) Copyright 2016 Manuel De Girardi.                                                                                                           --
--------------------------------------------------------------------------------------------------------------------------------------------------------------
  
--------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Date        := 2016-12-04 15:05:40 ; 
-- Description : Ada Generic Neural Object System Engineering.                                                                                              --
-- Version     := 2016.34.3a ; 
-- Authors     : Manuel De Girardi.                                                                                                                         --
--------------------------------------------------------------------------------------------------------------------------------------------------------------
with Ada.Wide_Text_Io;
use Ada;
with Gnat.Os_Lib;
use Gnat;
with Gnat.Command_Line;
use Gnat.Command_Line;
with Ada.Characters.Handling;
use Ada.Characters.Handling;

with Gnos.Tools;
use Gnos.Tools;
package body Gnos.Results is
use Os_Lib;
use type U_String;
   
   function Spawn(Line : in String) return Spawn_Result_Type is
      
      Command : Gnat.Command_Line.Command_Line;
      
      Spawn_Result : Spawn_Result_Type;
	        
      Buffer_args, Arguments_List : Os_Lib.Argument_List_Access;                  
      
      File : Wide_Text_Io.File_Type;      
      Deleted : Boolean := False;
      
      Exec_Path : Os_Lib.String_Access;
      Initialized : Boolean := False;
      
      
      Home : constant Os_Lib.String_Access := Getenv("HOME");
      
      Out_Filename : constant String := Home.all & "/.Adamanborg-out_file.txt";
      
   begin
      
      Set_Command_Line(Command, Line);
      
      Gnat.Command_Line.Build(Command, Arguments_List, False);
      
      if Arguments_List(1) /= null and then Arguments_List(1).all /= "" then
         
         
         if Arguments_List'length > 1 then
            
            Buffer_Args := new Argument_List(1..Arguments_List'length - 1);
            
            for I in 1..Arguments_List'length - 1 loop
	       
               Buffer_Args(I) := new String ' (Normalize_Quoted_argument(Arguments_List(I+1).all));
	       
            end loop;            
            
            Spawn_Result := (
                             Process_Id   => Invalid_Pid,			  
                             Program_Name => +To_Wide_String(Arguments_List(1).all),
                             Args          => Buffer_Args,
                             Output_File  => +To_Wide_String(Out_Filename),
                             Success      => False,
                             Return_Code  => 0,
                             Err_To_Out   => True,
                             File_content => null			    
                            );
            
            
            
            
         else
            
            
            Spawn_Result := (
                             Process_Id   => Invalid_Pid,                             
                             Program_Name => +To_Wide_String(Arguments_List(1).all),
                             Args          => new Argument_List  ' (1..0 => new String ' ("" & Character'Val(0))),
                             Output_File  => +To_Wide_String(Out_Filename),
                             Success      => False,
                             Return_Code  => 0,
                             Err_To_Out   => True,
                             File_content => null
                               
                            );
         end if;
         
         
         
         if Locate_Exec_On_Path(Arguments_List(1).all) /= null then
            Exec_Path := new String ' (Locate_Exec_On_Path(Arguments_List(1).all).all);         
                              

            if Is_Executable_File(Exec_Path.all) then                                             
               
               Spawn_Result.Process_Id := 
                 Non_Blocking_Spawn(Program_Name => Exec_Path.all,
                                    Args         => Spawn_Result.Args.all,                           
                                    Output_File  => To_String(-Spawn_Result.Output_File),
                                    Err_To_Out   => Spawn_Result.Err_To_out
                                   );
               
               if Spawn_Result.Process_Id /= Gnat.Os_Lib.Invalid_Pid then
                  
                  Gnat.Os_Lib.Wait_Process(Spawn_Result.Process_Id, Spawn_Result.Success);
                  
               end if;               
               
               Spawn_Result.File_Content := new Variadic_Array(1..1);
               
               Wide_Text_Io.Open(File, Wide_Text_Io.In_File, To_String(-Spawn_Result.Output_File), Form => "WCEM=8");

               while not Wide_Text_Io.End_Of_File(File) loop
		  begin
		     declare
			
			Line : constant Wide_String := Wide_Text_Io.Get_Line(File);
			Buffer : Variadic_Access;
		     begin
			if Spawn_Result.File_Content /= null then
			   
			   if Initialized then
			      Buffer := new Variadic_Array(1..(Spawn_Result.File_Content'Length)+1);
			      Buffer(Buffer'First..Buffer'Last-1) := Spawn_Result.File_Content.all;
			      Buffer(Buffer'Last) := (+(Line));
			   else
			      Buffer := new Variadic_Array(1..1);
			      Buffer(Buffer'Last) := (+(Line));
			      Initialized := True;
			   end if;

			   

			end if;
			Free(Spawn_Result.File_Content);
			Spawn_Result.File_Content := new Variadic_Array ' (Buffer.all);
			Free(Buffer);
			
		     end;
--		  exception
--		     when Constraint_Error =>
--			null;
		  end;
               end loop;
               
               Wide_Text_Io.Close(File);	 
               Delete_File (Name => To_String((-Spawn_Result.Output_File)), Success => deleted);
               
               if not Spawn_Result.Success then      
                  Spawn_Result.Return_Code := Gnat.Os_Lib.Errno;
               end if;
            else
               Spawn_Result.File_Content := new Variadic_Array ' (1 => (+(To_Wide_String(Arguments_List(1).all) & " : command not found.")));               
               Spawn_Result.Return_Code := 127;
            end if;
         else            
            Spawn_Result.File_Content := new Variadic_Array ' (1 => (+(To_Wide_String(Arguments_List(1).all) & " : command not found.")));               
            Spawn_Result.Return_Code := 127;
         end if;         
      else         
         Spawn_Result.File_Content := new Variadic_Array ' (1 => (+(To_Wide_String(Arguments_List(1).all) & " : command not found.")));                        
         Spawn_Result.Return_Code := 127;
      end if;
      
      return Spawn_Result;
   end Spawn;    
end Gnos.Results;