import java.io.*;
/*
autore:Klez

migliorato da marcopete87.
-modifiche apportate:
1) migliorato l'algoritmo di cifratura: ora utilizza una chiave variabile.
2) migliorata la velocità del programma tramite buffer.
3) migliorata la struttura del programma.
4) messaggio di errore FileNotFound più chiaro.
*/
public class FileXorer
{
	
	public static void main(String[] args)
	{
		
		String inputFileName = "";
		String outputFileName = "";
		int mask = 42;
		
		if(args.length == 3)
		{
			inputFileName = args[0];
			outputFileName = args[1];
			try
			{
				mask = Integer.parseInt(args[2]);
			}
			catch(NumberFormatException e)
			{
				printUsage(args);
				return;
			}
		}
		else if(args.length == 2)
		{
			inputFileName = args[0];
			outputFileName = args[1];
		}
		else if (args.length == 1)
		{
			inputFileName = args[0];
			outputFileName = args[0] + ".xor";
		}
		else
		{
			printUsage(args);
			return;
		}
		
		try
		{
			final int size=65536; /*
			Valore del buffer, modificabile a piacere
			BUFFER SIZE! modify it at your preference.
			*/
			File f=new File(inputFileName);
			long lunghezza=f.length();
			int passaggi=(int)(lunghezza/size);
			int resto=(int)(lunghezza%size);
			FileInputStream inFile = new FileInputStream(inputFileName);
			FileOutputStream outFile = new FileOutputStream(outputFileName);
			System.out.println("Working");
			byte cache[]=new byte[size]; //utilizzando un buffer, le operazioni i/o su files vengono notevolmente accelerate.
			for(int i=0; i<passaggi; i++){
				inFile.read(cache);
				for(int k=0; k<cache.length; k++){
					cache[k]=(byte)(cache[k]^mask);
					if(mask>=0xFF)
						mask=0;
					else{
						if(k%4==0)
							mask++;
					}
				}
				outFile.write(cache);
			}
			cache=new byte[resto];
			inFile.read(cache);
			inFile.close();
			for(int k=0; k<resto; k++){
				cache[k]=(byte)(cache[k]^mask);
				if(mask>=0xFF)
					mask=0;
				else
					if(k%2!=0)
						mask++;
			}
			outFile.write(cache);
			outFile.close();
			System.out.println("Done.");
		}
		catch(FileNotFoundException e)
		{
			System.out.println("Warning: "+inputFileName+" Not found.");
		}catch(IOException e)
		{
			System.out.println(e.getMessage());
		}
		
		
	}
	
	private static void printUsage(String[] args)
	{
		System.out.println("Usage: java FileXorer inputfilename [outputfilename] [mask]\n\tIf outputfilename is not specified,\n\tthe output file will be named inputfilename.xor");
		System.out.println("\tIf no mask is specified, the default is 42");
	}
}