with Ada.Text_Io;
use Ada;
with System.Os_Lib;
use System;
with Ada.Characters.Handling;
use Ada.Characters;
with Ada.Command_Line;
use Ada.Command_Line;
with Ada.Directories;
use Ada.Directories;
procedure Logname is
   
   function System(Cmd : in String) return Integer;
   pragma Import(C, System, "system");
   Errno : Integer := 0;
   
   Verax : Boolean := False;
   Args   : Os_Lib.Argument_List_Access := new Os_Lib.Argument_List(1..0);
   Pid    : Os_Lib.Process_Id;
   Prolog : Text_Io.File_Type;
   Ada    : Text_Io.File_Type;
   
begin

   Text_Io.Put("Name : ");
   declare
      Name : String(1..32) := (others => Character'Val(32));
      Top : Positive := 1;
      Available : Boolean := False;
      The_Char : Character := ' ';
   begin
      Get_Name :
      loop
	 begin
	    for Char in Top .. Name'last loop
	       
	       
	       Text_Io.Get_immediate(Name(Char));
	       case Name(Char) is
		  when Character'Val(10) | Character'Val(13) =>
		     Name(Char) := Character'Val(32);
		     exit Get_Name;
		  when Character'Val(127) | Character'Val(8) =>
		     if Top > 1 then
			Name(Top) := Character'Val(32);
			Name(Top - 1) := Character'Val(32);			
			Text_Io.Put(Character'Val(8) & Character'Val(32) & Character'Val(8));
			Top := Top - 1;
			exit;
		     end if;
		  when others =>

		     Text_Io.Put(Name(Char));
		     Top := Top + 1;
	       end case;
	    end loop;
	    
	 exception
	    when Text_Io.End_Error =>
	       null;
	 end;
      end loop Get_name;
      Name := Handling.To_Lower(Name);
      Text_Io.New_Line;
      
      Errno := System("echo is_name\(" & Name(Name'First..Top-1) & "\). | /usr/bin/swipl -q -f " & 
			Base_Name(Command_Name) & ".pl" & Character'Val(0));

      if Os_Lib.Is_Regular_File("./error.txt") then

	 Os_Lib.Delete_file("./error.txt", Verax);
	 Text_Io.Create(Prolog, Text_Io.Out_File, Name(Name'First..Top-1) & ".pl");
	 Text_Io.Put_Line(Prolog, "name(" & Name(Name'First..Top-1) & ").");
	 Text_Io.Put_Line(Prolog, "is_name(V) :-");
	 Text_Io.Put_Line(Prolog, " name(V), !,");
	 Text_Io.Put_Line(Prolog, " write('Eureka')");
	 Text_Io.Put_Line(Prolog, "; open('./error.txt', write, Stream),");
	 Text_Io.Put_Line(Prolog, "close(Stream),");
	 Text_Io.Put_Line(Prolog, "name(V), !,");
	 Text_Io.Put_Line(Prolog, "write('').");
	 Text_Io.Close(Prolog);
	 
	 Errno := System("ln -f -s logname bin/" & Name(Name'First..Top-1) & Character'Val(0));

	 if Errno = 0 then
	    Text_Io.Create(Ada, Text_Io.Out_File, Name(Name'First..Top-1) & ".adb");

	    
	    Text_Io.Put_line(Ada, "with Ada.Text_Io;");
	    Text_Io.Put_line(Ada, "use Ada;");
	    Text_Io.Put_line(Ada, "with System.Os_Lib;");
	    Text_Io.Put_line(Ada, "use System;");
	    Text_Io.Put_line(Ada, "with Ada.Characters.Handling;");
	    Text_Io.Put_line(Ada, "use Ada.Characters;");
	    Text_Io.Put_line(Ada, "with Ada.Command_Line;");
	    Text_Io.Put_line(Ada, "use Ada.Command_Line;");
	    Text_Io.Put_line(Ada, "with Ada.Directories;");
	    Text_Io.Put_line(Ada, "use Ada.Directories;");
	    
	    Text_Io.Put_line(Ada, "procedure " & Name(Name'First..Top-1) & " is");
	    Text_Io.New_Line(Ada);
	    Text_Io.Put_Line(Ada, "   function System(Cmd : in String) return Integer;");
	    Text_Io.Put_Line(Ada, "   pragma Import(C, System, ""system"");");
	    Text_Io.Put_Line(Ada, "   Errno : Integer := 0;");
	    Text_Io.Put_Line(Ada, "   Verax : Boolean := False;");   
	    Text_Io.Put_Line(Ada, "   Args   : Os_Lib.Argument_List_Access;");
	    Text_Io.Put_Line(Ada, "   Pid    : Os_Lib.Process_Id;");
	    Text_Io.Put_Line(Ada, "   Prolog : Text_Io.File_Type;");
	    Text_Io.Put_Line(Ada, "   Ada    : Text_Io.File_Type;");
	    Text_Io.Put_Line(Ada, "begin");
	    Text_Io.New_Line(Ada);
	    Text_Io.Put_Line(Ada, "   Text_Io.Put(""Name : "");");
	    Text_Io.Put_Line(Ada, "   declare");

	    Text_Io.Put_Line(Ada, "  Name : String(1..32) := (others => Character'Val(32));");
	    Text_Io.Put_Line(Ada, "  Top : Positive := 1;");
	    Text_Io.Put_Line(Ada, "   begin");
	    Text_Io.Put_Line(Ada, "        Get_Name :");
	    Text_Io.Put_Line(Ada, "      loop");
	    Text_Io.Put_Line(Ada, " begin");
	    Text_Io.Put_Line(Ada, "    for Char in Top .. Name'last loop");
	    Text_Io.Put_Line(Ada, "       Text_Io.Get_Immediate(Name(Char));");
	    Text_Io.Put_Line(Ada, "       case Name(Char) is");
	    Text_Io.Put_Line(Ada, "  when Character'Val(10) | Character'Val(13) =>");
	    Text_Io.Put_Line(Ada, "     Name(Char) := Character'Val(32);");
	    Text_Io.Put_Line(Ada, "     exit Get_Name;");
	    Text_Io.Put_Line(Ada, "  when Character'Val(127) | Character'Val(8) =>");
	    Text_Io.Put_Line(Ada, "     if Top > 1 then");
	    Text_Io.Put_Line(Ada, "Name(Top) := Character'Val(32);");
	    Text_Io.Put_Line(Ada, "Name(Top - 1) := Character'Val(32);");
	    Text_Io.Put_Line(Ada, "Text_Io.Put(Character'Val(13) & ""Name : "" & Name(1..Top-1) & Character'Val(8));");
	    Text_Io.Put_Line(Ada, "Top := Top - 1;");
	    Text_Io.Put_Line(Ada, "exit;");
	    Text_Io.Put_Line(Ada, "     end if;");
	    Text_Io.Put_Line(Ada, "  when others =>");
	    Text_Io.Put_Line(Ada, "     Text_Io.Put(Name(Char));");
	    Text_Io.Put_Line(Ada, "     Top := Top + 1;");
	    Text_Io.Put_Line(Ada, "       end case;");
	    Text_Io.Put_Line(Ada, "    end loop;");
	    
	    Text_Io.Put_Line(Ada, " exception");
	    Text_Io.Put_Line(Ada, "    when Text_Io.End_Error =>");
	    Text_Io.Put_Line(Ada, "       null;");
	    Text_Io.Put_Line(Ada, " end;");
	    Text_Io.Put_Line(Ada, "      end loop Get_name;"); 
	    Text_Io.Put_Line(Ada, "     Text_Io.Put_line(Character'Val(13) & ""Name : "" & name);");


	    Text_Io.New_Line(Ada);
	    Text_Io.Put_Line(Ada, "      Name := Handling.To_Lower(Name);");
	    Text_Io.Put_Line(Ada, "          Errno := System(""echo is_name\("" & Name(Name'First..Top-1) & ""\). | /usr/bin/swipl -q -f "" & ");
	    Text_Io.Put_Line(Ada, "Base_Name(Command_Name) & "".pl"" & Character'Val(0));");


	    Text_Io.Put_Line(Ada, "      if Errno /= 0 then");
	    Text_Io.Put_Line(Ada, "         Text_Io.Create(Prolog, Text_Io.Out_File, Name & "".pl"");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, ""name("" & Name & "")."");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, ""is_name(V) :-"");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, "" name(V), !,"");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, "" write('Eureka')"");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, ""; open('./error.txt', write, Stream),"");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, ""close(Stream),"");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, ""name(V), !,"");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Put_Line(Prolog, ""write('')."");");
	    Text_Io.Put_Line(Ada, "         Text_Io.Close(Prolog);");
	    Text_Io.Put_Line(Ada, "         Errno := System(""ln -f -s logname bin/"" & Name(Name'First..Top-1) & Character'Val(0));");
	    Text_Io.Put_Line(Ada, "         Errno := System(""/usr/bin/sh -c ""bin/"" & Name(Name'First..Top-1) & "" 1>> .Out"" & Character'Val(0));");

	    Text_Io.Put_Line(Ada, "      end if;");
	    Text_Io.Put_Line(Ada, "   end;");
	    Text_Io.Put_Line(Ada, "end " & Name & ";");
	    
	    Text_Io.Close(Ada);
	    Os_Lib.Set_Errno(-1);
	    Errno := System("/usr/bin/sh -c ""bin/" & Name(Name'First..Top-1) & """" & Character'Val(0));

	    
	 else
	    Text_Io.Put("Faillure");
	    Os_Lib.Set_Errno(-127);
	 end if;
      end if;
      Os_Lib.Set_Errno(0);
   end;
exception
   when Text_Io.End_Error =>
      Os_Lib.Set_Errno(0);
      Text_Io.Put_Line("bye!");
end Logname;
