-- This program is the last attempt of artificial intelligency with Ada.
-- Elhoim is Copyright (C) 2023 Manuel ; 
--
--   <one line to give the program's name and a brief idea of what it does.>
--   Copyright (C) 19yy  <name of author>
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program 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
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2023-05-01 20:03:01"
-- Version := "1.0.0a"
with Lib.Errors;
with Ada.Wide_Text_Io;
with Ada.Text_Io;
use Ada;
with Ada.Characters.Handling;
use Ada.Characters.Handling;
with Ada.Strings.UTF_Encoding.Strings;
use Ada.Strings.UTF_Encoding.Strings;
with Gnat.Os_Lib;
with Gnat.Command_Line;
use Gnat;
package body Lib.Option is
   
   use Errors;
   
   function Get_Options_From_Command_Line
     -- To get Options_Kit_array_Type from argument in command_line ;
     
     return Options_Kit_Array_Type is
      
      Options_Kit : constant Options_Kit_Array_Type := Full_Line_Options_Kit;
      
   begin
      -- D'abord je traite les arguments de la ligne de commande ;                 --
  Opt :
      loop	 
	 begin
	    loop
	       begin
		  case Command_Line.Getopt ("v q h v F: g: e: H: i: f: m: c: r l n: W: L: H: A: N u: a s:") is
		     
		     when ASCII.NUL => exit Opt;
		     when 'a' =>
			if Command_Line.Full_Switch /= "a" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(As_server).Is_Setted := True;
		     when 'F' =>
			if Command_Line.Full_Switch /= "F" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Config_Filename).Is_Setted := True;
			Options_Kit(Config_Filename).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
								     	
		     when 'e' =>
			if Command_Line.Full_Switch /= "e" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Username).Is_Setted := True;
			Options_Kit(Username).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
		     when 'A' =>		  
			if Command_Line.Full_Switch /= "A" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Address).Is_Setted := True;
			Options_Kit(Address).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
		     when 'i' =>
			if Command_Line.Full_Switch /= "i" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Input_Text).Is_Setted := True;
			Options_Kit(Input_Text).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));			
		     when 'N' =>
		     	if Command_Line.Full_Switch /= "N" then
		     	   raise Command_Line.Invalid_Switch;
		     	end if;
		     	Options_Kit(Term_name).Is_Setted := True;			
		     	Options_Kit(Term_name).Value :=
		     	  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
		     when 'q' =>
			if Command_Line.Full_Switch /= "q" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Quiet).Is_Setted := True;
		     when 'h' =>
			if Command_Line.Full_Switch /= "h" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Help).Is_Setted := True;
		     when 'v' =>
			if Command_Line.Full_Switch /= "v" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Version).Is_Setted := True;		  
		     when 'g' =>
			if Command_Line.Full_Switch /= "g" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Geometry).Is_Setted := True;
			Options_Kit(Geometry).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));			
		     when 'f' =>
			if Command_Line.Full_Switch /= "f" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Samples_Filename).Is_Setted := True;		  
			Options_Kit(Samples_Filename).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
		     when 'm' =>
					     
			if Command_Line.Full_Switch /= "m" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Max_Epochs).Is_Setted := True;		  
			Options_Kit(Max_Epochs).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
			
		     when 'c' =>
					     
			if Command_Line.Full_Switch /= "c" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Converged).Is_Setted := True;		  
			Options_Kit(Converged).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
		     when 'r' =>
					     
			if Command_Line.Full_Switch /= "r" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Reuse).Is_Setted := True;		  
		     when 'l' =>
					     
			if Command_Line.Full_Switch /= "l" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(train).Is_Setted := True;		  			
		     when 'n' =>						
			if Command_Line.Full_Switch /= "n" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Num_samples).Is_Setted := True;		  
			Options_Kit(Num_Samples).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
		     when 'W' =>
			if Command_Line.Full_Switch /= "W" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Line_width).Is_Setted := True;
			Options_Kit(Line_width).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
								     			     
		     when 'H' =>		  
			if Command_Line.Full_Switch /= "H" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Num_hidden).Is_Setted := True;
			Options_Kit(Num_hidden).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));
		     when 'L' =>
			if Command_Line.Full_Switch /= "L" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(Words_max).Is_Setted := True;
			Options_Kit(Words_Max).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));			
		     when 'u' =>
			if Command_Line.Full_Switch /= "u" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(update).Is_Setted := True;
			Options_Kit(update).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));			
		     when 's' =>
			if Command_Line.Full_Switch /= "s" then
			   raise Command_Line.Invalid_Switch;
			end if;
			Options_Kit(style).Is_Setted := True;
			Options_Kit(Style).Value :=
			  new Wide_String ' (To_Wide_String(Decode(Command_Line.Parameter)));			
		     
		     when others =>
			raise Program_Error;         -- cannot occur!
		  end case;
		  
		  
	       exception
		  when Command_Line.Invalid_Switch    => Text_Io.Put_Line ("Invalid Switch " & Command_Line.Full_Switch);
		     
		     raise;
		     
		  when Command_Line.Invalid_Parameter =>
		     
		     raise Spec_Error;
		     		  
	       end;
		  
	    end loop;      
	 exception
	    when Spec_Error =>
	       Text_Io.Put_Line ("No parameter for " & Command_Line.Full_Switch);
	       raise;
	       
	 end;
      end loop opt;
      
      return Options_Kit;
      

      
      
   end Get_Options_From_Command_Line;

   
   
   function Get_Options_From_File
     (Filename : in Wide_String)
     -- To get Options_Kit_array_Type from argument in file ;
     
     return Options_Kit_Array_Type is
      Options_Kit : constant Options_Kit_Array_Type := Full_File_Options_Kit;
      File : Wide_Text_Io.File_Type;
   begin     
      if Os_Lib.Is_Regular_File(To_String(Filename)) then
	 Wide_Text_Io.Open(File, Wide_Text_Io.In_File, To_String(Filename));
	 while not Wide_Text_Io.End_Of_File(File) loop

	    declare
	       Line   : constant Wide_String := Wide_Text_Io.Get_Line(File);
	       Switch : constant Character := To_Character(Line(Line'First));
	       Parameter : access String;
	    begin
	       
	       if Line'Length > 1 then
		  Parameter := new String ' (To_String(Line(Line'First+1..Line'last)));
	       end if;
	       
	       case Switch is
		  
		  when 'a' =>
		     
		     Options_Kit(As_server).Is_Setted := True;		  
		  
		  when 'F' =>
		     
		     Options_Kit(Config_Filename).Is_Setted := True;
		     Options_Kit(Config_Filename).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		     
		  when 'A' =>		  
		     
		     Options_Kit(Address).Is_Setted := True;
		     Options_Kit(Address).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		  when 'i' =>		  
		     
		     Options_Kit(Input_Text).Is_Setted := True;
		     Options_Kit(Input_Text).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		  when 'N' =>		  
		     
		     Options_Kit(Term_name).Is_Setted := True;
		     Options_Kit(Term_name).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));

		  when 'g' =>
		     
		     Options_Kit(Geometry).Is_Setted := True;		  
		     Options_Kit(geometry).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		  when 'q' =>
		     
		     Options_Kit(Quiet).Is_Setted := True;
		  when 'h' =>
		     
		     Options_Kit(Help).Is_Setted := True;		  
		     
		  when 'e' =>
		     
		     Options_Kit(Username).Is_Setted := True;
		     Options_Kit(Username).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));		  
		  when 'v' =>
		     
		     Options_Kit(Version).Is_Setted := True;
		     
		  when 'f' =>		  
		     
		     Options_Kit(Samples_filename).Is_Setted := True;
		     Options_Kit(Samples_filename).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		     
		  when 'm' =>		  
		     
		     Options_Kit(Max_Epochs).Is_Setted := True;
		     Options_Kit(Max_Epochs).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		     
		  when 'c' =>		  
		     
		     Options_Kit(Converged).Is_Setted := True;
		     Options_Kit(Converged).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));

		  when 'r' =>		  
		     
		     Options_Kit(Reuse).Is_Setted := True;

		  when 'l' =>		  
		     
		     Options_Kit(Train).Is_Setted := True;
		     
		  when 'n' =>		  
		     
		     Options_Kit(Num_samples).Is_Setted := True;
		     Options_Kit(Num_Samples).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		     
		  when 'W' =>		  
		     
		     Options_Kit(Line_width).Is_Setted := True;
		     Options_Kit(Line_width).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		     
		  when 'L' =>		  
		     
		     Options_Kit(Words_Max).Is_Setted := True;
		     Options_Kit(Words_Max).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		     
		  when 'H' =>
		     
		     Options_Kit(Num_Hidden).Is_Setted := True;
		     Options_Kit(Num_Hidden).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		  when 'u' =>
		     
		     Options_Kit(update).Is_Setted := True;
		     Options_Kit(update).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		  when 's' =>
		     
		     Options_Kit(style).Is_Setted := True;
		     Options_Kit(style).Value :=
		       new Wide_String ' (To_Wide_String(Decode(Parameter.all)));
		  when others =>
		     null;
	       end case;
	       
	    end;
	 end loop;

	 
	 
	 Wide_Text_Io.Close(File);
      end if;
     return Options_Kit;
   end Get_Options_From_File;   
   
end Lib.Option ;