with Ada.Unchecked_Conversion;
with Interfaces.C;

use Interfaces.C;

package body FILO.FS.VFS is

   State : T := Initial;

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

   subtype Path_Length is Natural range 0 .. Path_Max;
   subtype Path_Index_Plus is Positive range 1 .. Path_Max + 1;
   subtype Path_Index is Path_Index_Plus range 1 .. Path_Max;

   subtype Path_Buffer is Buffer_Type (Path_Index)
   with
      Object_Size => Path_Max * 8;
   Path_Buf : Path_Buffer;

   subtype Path_String is String (Path_Index)
   with
      Object_Size => Path_Max * 8;
   Path : Path_String;

   function C_Mount return int
   with
      SPARK_Mode => Off
   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;

   procedure Open (File_Path : System.Address; Ret : out int)
   is
      function Str_Len (S : System.Address) return Natural;
      function Str_Len (S : System.Address) return Natural
      with
         SPARK_Mode => Off
      is
         Buf : Buffer_Type (1 .. Path_Max + 1)
         with
            Convention => C,
            Address => S;
      begin
         for I in Buf'Range loop
            if Buf (I) = 16#00# then
               return I - 1;
            end if;
         end loop;
         return Path_Max + 1;
      end Str_Len;

      procedure Str_Cpy (Dst : out String; Src : in System.Address);
      procedure Str_Cpy (Dst : out String; Src : in System.Address)
      with
         SPARK_Mode => Off
      is
         Src_String : String (Dst'Range)
         with
            Convention => C,
            Address => Src;
      begin
         Dst := Src_String;
      end Str_Cpy;

      function Component_Start (Path : Path_String; Pos : Positive) return Path_Index_Plus 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 : Path_String; Start : Path_Index_Plus; Limit : Path_Index) return Path_Length
      with
         Post => Component_End'Result <= Limit
      is
      begin
         for I in Start .. Limit loop
            if Path (I) = '/' or Is_Space (Path (I)) then
               return I - 1;
            end if;
         end loop;
         return Limit;
      end Component_End;

      function Path_End (Path : Path_String; Start : Path_Index) return Path_Length 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     Path_Index_Plus;
         Rest_Last   : in     Path_Index;
         Link_Len    : in     Natural;
         Success     :    out Boolean)
      with
         Pre =>
            Is_Open (State) and
            Rest_First - 1 <= Rest_Last,
         Post =>
            Is_Open (State)
      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 Natural := Str_Len (File_Path);
      Root_Dir : Boolean := True;
   begin
      Ret := 0;

      if not Is_Mounted (State) or Path_Len > Path_Max then
         return;
      end if;

      Str_Cpy (Path (1 .. Path_Len), File_Path);
      Path (Path_Len + 1 .. Path'Last) := (others => ' ');

      Link_Loop :
      for I in 1 .. Max_Link_Depth loop
         pragma Loop_Invariant (Is_Mounted (State));
         declare
            Path_Pos : Path_Index_Plus := Path'First;
            Path_Last : constant Path_Length := Path_End (Path, Path_Pos);
         begin
            if Path_Last < Path'First then
               return;
            end if;

            Path_Loop :
            loop
               pragma Loop_Invariant
                 (Is_Mounted (State) and
                  Path_Last in Path'Range);
               declare
                  Comp_First : constant Path_Index_Plus := Component_Start (Path, Path_Pos);
                  Comp_Last : constant Path_Length := Component_End (Path, Comp_First, Path_Last);
                  File_Type : FS.File_Type;
                  File_Len : File_Length;
                  Success : Boolean;
               begin
                  if Comp_First > Comp_Last then
                     return;
                  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;
                  end if;
                  Root_Dir := False;

                  case File_Type is
                     when Dir =>
                        if Comp_Last = Path_Last then
                           Close (State);
                           return;
                        end if;
                        Path_Pos := Comp_Last + 1;
                     when Regular =>
                        if Comp_Last = Path_Last then
                           Set_File_Max (File_Len);
                           Ret := 1;
                           return;
                        else
                           Close (State);
                           return;
                        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;
                        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;
   end Open;

   function C_Open (File_Path : System.Address) return int
   with
      SPARK_Mode => Off
   is
      Ret : int;
   begin
      if Is_Mounted (State) then
         Open (File_Path, Ret);
      else
         Ret := 0;
      end if;
      return Ret;
   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
   with
      SPARK_Mode => Off
   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;
