with GNATCOLL.Iconv;   use GNATCOLL.Iconv;
with GNAT.IO;          use GNAT.IO;

procedure Test_Iconv is
   procedure Assert
      (Input, Expected, From_Code, To_Code : String;
       Transliteration, Ignore : Boolean := False;
       Invalid_Sequence : Boolean := False);

   procedure Assert
      (Input, Expected, From_Code, To_Code : String;
       Transliteration, Ignore : Boolean := False;
       Invalid_Sequence : Boolean := False)
   is
   begin
      declare
         R : constant String := Iconv
            (Input => Input, To_Code => To_Code, From_Code => From_Code,
             Transliteration => Transliteration, Ignore => Ignore);
      begin
         if Invalid_Sequence then
            Put_Line ("======= Error converting " & Input & " to " & To_Code);
            Put_Line ("- Expected an invalid sequence error");
            Put_Line ("+ " & R);
         elsif R /= Expected then
            Put_Line ("======= Error converting " & Input & " to " & To_Code
                      & " Ignore=" & Ignore'Img
                      & " Transliteration=" & Transliteration'Img);
            Put_Line ("- " & Expected);
            Put_Line ("+ " & R);
            for C in R'Range loop
               Put (Character'Pos (R (C))'Img);
            end loop;
            New_Line;
         end if;
      end;

   exception
      when Invalid_Sequence_Error =>
         if not Invalid_Sequence then
            Put_Line ("======= Error converting " & Input & " to " & To_Code
                      & " Ignore=" & Ignore'Img
                      & " Transliteration=" & Transliteration'Img);
            Put_Line ("- " & Expected);
            Put_Line ("+ An invalid sequence error");
         end if;
   end Assert;

   Eacute : constant Character := Character'Val (16#E9#);
   --  in Iso_8859-1

   R_Koi8 : constant Character := Character'Val (16#D1#);
   EAcute_Koi8_Trans : constant String :=  --  a 'e
      Character'Val (39) & Character'Val (101);
   --  In KOI8-R

   Eacute_UTF8 : constant String :=
      Character'Val (195) & Character'Val (169);
   R_UTF8 : constant String :=
      Character'Val (209) & Character'Val (143);

begin
   if not Has_Iconv then
      return;
   end if;
   Assert ("Simple test", "Simple test", "", "");
   Assert ("Simple " & Eacute, "Simple " & Eacute_UTF8, Iso_8859_1, UTF8);
   Assert ("Simple " & R_Koi8, "Simple " & R_UTF8, KOI8_R, UTF8);

   Assert
      ("Simple " & Eacute, "Simple ", Iso_8859_1, KOI8_R,
       Invalid_Sequence => True);

   --  Test with invalid character both in the middle and at the end
   Assert
      ("Simple " & Eacute, "Simple ", Iso_8859_1, KOI8_R,
       Ignore => True, Invalid_Sequence => False);
   Assert
      ("T" & Eacute & "Simple", "TSimple", Iso_8859_1, KOI8_R,
       Ignore => True, Invalid_Sequence => False);

   --  We do not test transliteration, which is only supported by GNU
   --  libiconv, and is not guaranteed to do anything in any case. Since we
   --  are not testing libiconv itself, only our binding, no need to test.
   --  Assert
   --     ("Simple " & Eacute, "Simple " & EAcute_Koi8_Trans, Iso_8859_1,
   --      KOI8_R, Transliteration => True, Invalid_Sequence => False);
end Test_Iconv;
