with Ada.Unchecked_Conversion;
with Interfaces.C;
with Interfaces.C.Strings;

use Interfaces.C;

package body FILO.FS.VFS
with
   SPARK_Mode => Off
is

   State : T := Initial;

   Path_Max : constant := 4096;
   Max_Link_Depth : constant := 32;

   subtype Path_Buffer is Buffer_Type (1 .. Path_Max);
   Path_Buf : Path_Buffer;

   subtype Path_String is String (1 .. Path_Max);
   Path : Path_String;

   function C_Mount return int
   is
      Success : Boolean;
   begin
      if not Is_Mounted (State) then
         State := Initial; -- Work around not having an unmount in FILO.
      end if;
      Mount (State, Part_Len, Success);
      return (if Success then 1 else 0);
   end C_Mount;

   function C_Open (File_Path : Strings.chars_ptr) return int
   is
      function Component_Start (Path : String; Pos : Positive) return Positive is
      begin
         for I in Pos .. Path'Last loop
            if Path (I) /= '/' then
               return I;
            end if;
         end loop;
         return Path'Last + 1;
      end Component_Start;

      function Component_End (Path : String; Start : Positive) return Positive is
      begin
         for I in Start .. Path'Last loop
            if Path (I) = '/' or Is_Space (Path (I)) then
               return I - 1;
            end if;
         end loop;
         return Path'Last;
      end Component_End;

      function Path_End (Path : String; Start : Positive) return Positive is
      begin
         for I in Start .. Path'Last loop
            if Is_Space (Path (I)) then
               return I - 1;
            end if;
         end loop;
         return Path'Last;
      end Path_End;

      procedure Read_Link
        (Path        : in out Path_String;
         Rest_First  : in     Positive;
         Rest_Last   : in     Positive;
         Link_Len    : in     Natural;
         Success     :    out Boolean)
      is
         function As_String is new Ada.Unchecked_Conversion (Path_Buffer, Path_String);

         Rest_Len : constant Natural := Rest_Last - Rest_First + 1;
         File_Pos : File_Offset := 0;
         Read_Len : Natural;
      begin
         if Path_Max - Rest_Len < Link_Len then
            Success := False;
            return;
         end if;

         Read
           (State    => State,
            File_Pos => File_Pos,
            Buf      => Path_Buf (1 .. Link_Len),
            Len      => Read_Len);
         Success := Read_Len = Link_Len;

         if Success then
            Path (Link_Len + 1 .. Link_Len + Rest_Len) := Path (Rest_First .. Rest_Last);
            Path (Link_Len + Rest_Len + 1 .. Path'Last) := (others => ' ');
            Path (1 .. Link_Len) := As_String (Path_Buf) (1 .. Link_Len);
         end if;
      end Read_Link;

      Path_Len : constant size_t := Strings.Strlen (File_Path);
      Root_Dir : Boolean := True;
   begin
      if not Is_Mounted (State) or Path_Len > Path_Max then
         return 0;
      end if;

      Path (1 .. Natural (Path_Len)) := Strings.Value (File_Path);
      Path (Natural (Path_Len + 1) .. Path'Last) := (others => ' ');

      Link_Loop :
      for I in 1 .. Max_Link_Depth loop
         declare
            Path_Pos : Positive := Path'First;
            Path_Last : constant Positive := Path_End (Path, Path_Pos);
         begin
            Path_Loop :
            loop
               declare
                  Comp_First : constant Positive := Component_Start (Path, Path_Pos);
                  Comp_Last : constant Positive := Component_End (Path, Comp_First);
                  File_Type : FS.File_Type;
                  File_Len : File_Length;
                  Success : Boolean;
               begin
                  if Comp_First > Comp_Last then
                     return 0;
                  end if;

                  Open
                    (State       => State,
                     File_Len    => File_Len,
                     File_Type   => File_Type,
                     File_Name   => Path (Comp_First .. Comp_Last),
                     In_Root     => Root_Dir,
                     Success     => Success);
                  if not Success then
                     return 0;
                  end if;
                  Root_Dir := False;

                  case File_Type is
                     when Dir =>
                        if Comp_Last = Path_Last then
                           Close (State);
                           return 0;
                        end if;
                        Path_Pos := Comp_Last + 1;
                     when Regular =>
                        if Comp_Last = Path_Last then
                           Set_File_Max (File_Len);
                           return 1;
                        else
                           Close (State);
                           return 0;
                        end if;
                     when Link =>
                        if File_Len > Path_Max then
                           Success := False;
                        else
                           Read_Link
                             (Path        => Path,
                              Rest_First  => Comp_Last + 1,
                              Rest_Last   => Path_Last,
                              Link_Len    => Natural (File_Len),
                              Success     => Success);
                        end if;
                        Close (State);
                        if not Success then
                           return 0;
                        end if;
                        Root_Dir := Path (1) = '/';
                        exit Path_Loop; -- continue in Link_Loop
                  end case;
               end;
            end loop Path_Loop;
         end;
      end loop Link_Loop;

      return 0;
   end C_Open;

   procedure C_Close is
   begin
      if Is_Open (State) then
         Close (State);
      end if;
   end C_Close;
   
   function C_Read (Buf : System.Address; Len : int) return int
   is
      subtype Buffer_Range is Natural range 0 .. Integer (Len) - 1;
      Buffer : Buffer_Type (Buffer_Range)
      with
         Convention => C,
         Address => Buf;

      File_Pos : File_Offset := FILO.FS.File_Pos;
      Read_Len : Natural;
   begin
      if Is_Open (State) then
         Read (State, File_Pos, Buffer, Read_Len);
         Set_File_Pos (File_Pos);
      else
         Read_Len := 0;
      end if;
      return int (Read_Len);
   end C_Read;

end FILO.FS.VFS;
