------------------------------------------------------------------------------
--                                  Log4Ada                                 --
--                                                                          --
--                          Copyright (C) 2007-2009                         --
--                              X. Grave CNRS                               --
--                                                                          --
--  This library 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 library 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 library; if not, write to the Free Software Foundation, --
--  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.          --
--                                                                          --

package body Log4ada.Appenders.Files is

   ----------
   -- Open --
   ----------

   procedure Open
     (File : not null access File_Type;
      Name : String)
   is
   begin
      if File.File_Open then
         return;
      end if;
      File.File_Name := Ada.Strings.Unbounded.To_Unbounded_String (Name);
      Ada.Text_IO.Create (File.File,
                          Name => Name & ".0");
      File.File_Open := True;
   end Open;

   -------------
   -- Refresh --
   -------------

   procedure Refresh (File : not null access File_Type) is
   begin
      if not File.File_Open then
         return;
      end if;
      File.Current_Number := File.Current_Number + 1;
      Close (File);
      File.File_Open := False;
      declare
         Number_Image : constant String := Natural'Image (File.Current_Number);
      begin
         Ada.Text_IO.Create
           (File.File,
            Name => Ada.Strings.Unbounded.To_String (File.File_Name) & "." &
            Number_Image (Number_Image'First + 1 .. Number_Image'Last));
      end;
      File.Current_Size := 0;
      File.File_Open := True;
   end Refresh;

   -----------
   -- Close --
   -----------

   procedure Close (File : not null access File_Type) is
   begin
      if File.File_Open then
         Ada.Text_IO.Close (File.File);
         File.File_Open := False;
      end if;
   end Close;

   ------------
   -- Append --
   ------------

   function Event_Size (Event : Events.Event_Type) return File_Size_Type;

   procedure Append
     (File : not null access File_Type;
      Event : Events.Event_Type)
   is
      Timestamp_Diff : Integer;
      use Events;
   begin
      if not File.Enabled then
         return;
      end if;
      if not Continue (File, Event) then
         return;
      end if;
      if not File.File_Open then
         return;
      end if;
      if File.Current_Size + Event_Size (Event) > File.Max_Size then
         Refresh (File);
      end if;
      Timestamp_Diff := Get_Timestamp (Event) - Events.First_Event_Timestamp;
      Ada.Text_IO.Put (File.File, Timestamp_Diff'Img & " ");
      Ada.Text_IO.Put (File.File, Get_Level (Event)'Img & " [");
      Ada.Text_IO.Put (File.File, Get_Location_Information (Event) & "] ");
      Ada.Text_IO.Put (File.File, Get_Logger_Name (Event) & " - ");
      Ada.Text_IO.Put (File.File, Get_Message (Event));
      if Exception_Present (Event) then
         Ada.Text_IO.Put (File.File, " - " & Get_Exception_Name (Event));
         Ada.Text_IO.Put_Line (File.File,
                               " - " & Get_Exception_Message (Event));
      else
         Ada.Text_IO.New_Line (File.File);
      end if;
      File.Current_Size := File.Current_Size + Event_Size (Event);
      Ada.Text_IO.Flush (File.File);
   end Append;

   function Event_Size (Event : Events.Event_Type) return File_Size_Type is
      Event_Size : File_Size_Type := 0;
      Timestamp_Diff : Integer;
      use Events;
   begin
      Timestamp_Diff := Get_Timestamp (Event) - Events.First_Event_Timestamp;
      Event_Size := Timestamp_Diff'Img'Length + 1;
      Event_Size := Event_Size + Get_Level (Event)'Img'Length + 2;
      Event_Size := Event_Size +  Get_Location_Information (Event)'Length + 2;
      Event_Size := Event_Size + Get_Logger_Name (Event)'Length + 3;
      Event_Size := Event_Size +  Get_Message (Event)'Length;
      if Exception_Present (Event) then
         Event_Size := Event_Size + Get_Exception_Name (Event)'Length + 3;
         Event_Size := Event_Size + Get_Exception_Message (Event)'Length + 4;
      else
         Event_Size := Event_Size + 1;
      end if;
      return Event_Size;
   end Event_Size;

   procedure Set_File_Max_Size (File : not null access File_Type;
                                Size : File_Size_Type) is
   begin
      File.Max_Size := Size;
   end Set_File_Max_Size;

end Log4ada.Appenders.Files;
