package BlowfishJ;

import java.io.*;

//import junit.framework.*;

/**
 * Simple tests for the BlowfishInputStream and BlowfishOutputStream.
 * @author Dale Anson (danson@germane-software.com), February, 2002
 */
public class InOutputStreamTest /*extends TestCase*/ {
   public InOutputStreamTest(String name) {
      //super(name);
   }

   /**
    * This test encrypts a string, then decrypts the encrypted string, then checks
    * that the decrypted string is the same as the original string.
    */
   public static void testStreams() {
      try {
         //String test_string = "1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ !@#$%^&*()_+<>?:\"{}|_+-=[]\\;',./`~";
         String test_string = "12345678";
         
         // convert test string to bytes
         byte[] bytes = test_string.getBytes();

         // create a byte stream to read from
         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

         // and create a stream to write to
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         BlowfishOutputStream bos = new BlowfishOutputStream("password", baos);

         // write out encrypted bytes
         int in;
         while ( (in = bais.read()) > -1 ) {
            bos.write(in);
         }
         bos.flush();
         bos.close();

         // create a byte stream to read the encrypted bytes from
         bytes = baos.toByteArray();
         bais = new ByteArrayInputStream(bytes);

         // create a stream to decrypt the bytes
         BlowfishInputStream bis = new BlowfishInputStream("password", bais);

         // read the decrypted bytes
         StringBuffer sb = new StringBuffer();
         while ( (in = bis.read()) > -1 ) {
            sb.append((char)in);
         }
         bis.close();
         //assert(test_string.equals(sb.toString()));
         if ( !test_string.equals(sb.toString()) ) {
            throw new Exception("TEXT TEST FAILED!");
         }
         else {
            System.out.println("TEXT TEST PASSED!");
         }

      }
      catch ( Exception e ) {
         e.printStackTrace();
      }
   }

   /**
    * This test reads a file, encrypts the file, decrypts the encrypted file, then
    * compares the decrypted file with the original file. The test passes if the
    * decrypted file and the original file are byte-by-byte identical. On a large file,
    * this test will be slow as there isn't any buffering done.
    * @param test_file file to read.
    */
   public static void testStreams2(String test_file) {
      try {
         File original = new File(test_file);

         // read in a file and write it out encrypted
         FileInputStream fis = new FileInputStream(original);
         File encrypted = File.createTempFile("enc", ".enc");
         encrypted.deleteOnExit();
         FileOutputStream fos = new FileOutputStream(encrypted);
         BlowfishOutputStream bos = new BlowfishOutputStream("password", fos);

         int in;
         while ( (in = fis.read()) > -1 ) {
            bos.write(in);
         }
         bos.close();

         // read in the encrypted file and write it out decrypted
         fis = new FileInputStream(encrypted);
         BlowfishInputStream bis = new BlowfishInputStream("password", fis);
         File decrypted = File.createTempFile("dec", ".dec");
         decrypted.deleteOnExit();
         fos = new FileOutputStream(decrypted);

         while ( (in = bis.read()) > -1 ) {
            fos.write(in);
         }
         fos.close();

         // check the decrypted file against the original file
         if ( decrypted.length() != original.length() )
            throw new Exception("FILE TEST FAILED: Files are different size.");

         fis = new FileInputStream(original);
         FileInputStream fis2 = new FileInputStream(decrypted);
         int in2;
         while ( (in = fis.read()) > -1 ) {
            in2 = fis2.read();
            if ( in2 != in ) {
               fis.close();
               fis2.close();
               throw new Exception("FILE TEST FAILED: Files don't match.");
            }
         }
         fis.close();
         fis2.close();
         System.out.println("FILE TEST PASSED!");
      }
      catch ( Exception e ) {
         e.printStackTrace();
      }
   }

   /**
    * To test file encryption/decryption, pass a file name as the first argument.
    */
   public static void main(String[] args) {
      testStreams();
      if ( args.length > 0 )
         testStreams2(args[0]);
      else
         System.out.println("FILE TEST NOT PERFORMED (need to pass a file name on the command line).");
   }
}
