/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package buzzerproxy;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.*;

/**
 * Quelle: http://download.oracle.com/javase/6/docs/api/java/util/zip/Inflater.html 
 * Quelle: http://www.coderanch.com/t/374637/java/java/Compressing-Decompressing-strings-Java
 * @author IBB-Teilnehmer
 */
public final class Gzip {

    public SecureRandom random = new SecureRandom();
    public final int FileNameLenght = 512;

    public final String gzip(String str) {
        
        if ( str == null || !(str instanceof String)){
            Exception e = new Exception();
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
            System.exit(1);
        } // if ( str == null || !(str instanceof String)){
        
        Writer writer = null;
        
        try {
            String longFilename = new BigInteger(130, random).toString(FileNameLenght);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(longFilename + ".gz");
            } catch (FileNotFoundException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                writer = new OutputStreamWriter(new GZIPOutputStream(output), "UTF-8");
            } catch (IOException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                writer.write(str);
            } catch ( IOException e ){
                 Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
            } finally {
                try {
                    writer.close();
                } catch (IOException ex) {
                    Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
                }
                try {
                    output.close();
                } catch (IOException ex) {
                    Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            return longFilename + ".gz";
        } finally {
            try {
                writer.close();
            } catch (IOException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    } //  public final String gzip(String str) throws IOException {

    public final String gunzipString(String str) {

        if ( str == null || !(str instanceof String)){
            Exception e = new Exception();
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
            System.exit(1);
        } // if ( str == null || !(str instanceof String)){
        
        
        String longFilename = new BigInteger(130, random).toString(FileNameLenght);

        try {
            BufferedWriter out = new BufferedWriter(new FileWriter(longFilename));
            out.write(str);
            out.close();
        } catch (IOException e) {
            System.out.println("Exception ");
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
        }

        String returnContent = this.gunzip(longFilename);
        deleteFiles(longFilename);
        return returnContent;

    } // public final String gunzipString(String input) {

    
    public final String gunzip(String filename) {
        
        if ( filename == null || !(filename instanceof String)){
            Exception e = new Exception();
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
            System.exit(1);
        } // if ( str == null || !(str instanceof String)){
        
        
        OutputStream out = null;
        GZIPInputStream in = null;
        String returnValue = "";
        
        try {
            String longFilename = new BigInteger(130, random).toString(FileNameLenght);
            String longFilenameFinal = longFilename + ".txt";
            
            // Open the compressed file
            try {
                in = new GZIPInputStream(new FileInputStream(filename));
            } catch (IOException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            out = new FileOutputStream(longFilenameFinal);
            
            // Transfer bytes from the compressed file to the output file
            byte[] buf = new byte[1024];
            int len;
            try {
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } catch (IOException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                // Close the file and stream
                in.close();
            } catch (IOException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                out.close();
            } catch (IOException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
           
            returnValue = readFileAsString(longFilenameFinal);
           
            if (deleteFiles(filename, longFilenameFinal)) {
                System.out.println("Gzip-gzip(): Delete Files successfull");
            } else {
                System.out.println("Gzip-gzip(): Delete File not successfull");
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return returnValue;
        
    } // public final String gunzip(String filename) {

    private Boolean deleteFiles(String gz) {
        
        if ( gz == null || !(gz instanceof String)){
            Exception e = new Exception();
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
            System.exit(1);
        } // if ( str == null || !(str instanceof String)){
        
        // delete file
        File f = new File(gz);
        // Attempt to delete it
        boolean success = f.delete();

        if (!success) {
            System.out.println("Delete: deletion failed: " +gz);
        }

        if (success) {
            return true;
        } else {
            return false;
        }
        
    } // private Boolean deleteFiles(String gz) {

    
    private Boolean deleteFiles(String gz, String txt) {

        if ( gz == null || !(gz instanceof String) || txt == null || !(txt instanceof String)){
            Exception e = new Exception();
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
            System.exit(1);
        } // if ( str == null || !(str instanceof String)){
        
        
        // delete file
        File f = new File(gz);
        // Attempt to delete it
        boolean success = f.delete();

        if (!success) {
            System.out.println("Delete: deletion failed" + gz + txt);
        }

        // delete file
        File ff = new File(txt);
        // Attempt to delete it
        boolean successf = ff.delete();

        if (!successf) {
            System.out.println("Delete: deletion failed");
        }

        if (success && successf) {
            return true;
        } else {
            return false;
        }

    } // private Boolean deleteFiles(String gz, String txt) {

    
    public String readFileAsString(String filePath){

        if ( filePath == null || !(filePath instanceof String)){
            Exception e = new Exception();
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
            System.exit(1);
        } // if ( str == null || !(str instanceof String)){
       
        StringBuilder fileData = new StringBuilder(1000);
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(filePath));
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
        }
        char[] buf = new char[1024];
        int numRead = 0;
        try {
            while ((numRead = reader.read(buf)) != -1) {
                String readData = String.valueOf(buf, 0, numRead);
                fileData.append(readData);
                buf = new char[1024];
            }
        } catch (IOException ex) {
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            reader.close();
        } catch (IOException ex) {
            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
        }
        return fileData.toString();
    } // public String readFileAsString(String filePath){
} // Class Gzip


//////////////
//////////////    private static final int ZIP_BUFFER_SIZE = 2048;
//////////////
//////////////    public static final byte[] gzip(String str) throws UnsupportedEncodingException
//////////////    {
//////////////
//////////////        byte[] input = str.getBytes("UTF-8");
//////////////        byte[] output = new byte[32768];
//////////////        Deflater deflater = new Deflater(1);
//////////////        deflater.setInput(input);
//////////////        deflater.finish();
//////////////        int compressedDataLength = deflater.deflate(output);
//////////////        System.out.println(output);
//////////////
////////////////        return Base64.encode(output.toString()); // rückwarts: Base64.decode(String).getBytes("UTF-8");
//////////////        return output;
//////////////
//////////////    }
//////////////
//////////////    public static final String gunzip(byte[] str) throws UnsupportedEncodingException
//////////////    {
//////////////
//////////////        byte[] byReturn = null;
//////////////        Inflater oInflate = new Inflater(true);
//////////////        oInflate.setInput(str);
//////////////        ByteArrayOutputStream oZipStream = new ByteArrayOutputStream();
//////////////        try
//////////////        {
//////////////            while (!oInflate.finished())
//////////////            {
//////////////                byte[] byRead = new byte[ZIP_BUFFER_SIZE];
//////////////                int iBytesRead = oInflate.inflate(byRead);
//////////////                if (iBytesRead == byRead.length)
//////////////                {
//////////////                    try
//////////////                    {
//////////////                        oZipStream.write(byRead);
//////////////                    } catch (IOException ex)
//////////////                    {
//////////////                        Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
//////////////                    }
//////////////                } else
//////////////                {
//////////////                    oZipStream.write(byRead, 0, iBytesRead);
//////////////                }
//////////////            }
//////////////            byReturn = oZipStream.toByteArray();
//////////////        } catch (DataFormatException ex)
//////////////        {
//////////////            try
//////////////            {
//////////////                throw new IOException("Attempting to unzip file that is not zipped.");
//////////////            } catch (IOException ex1)
//////////////            {
//////////////                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex1);
//////////////            }
//////////////        } finally
//////////////        {
//////////////            try
//////////////            {
//////////////                oZipStream.close();
//////////////            } catch (IOException ex)
//////////////            {
//////////////                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
//////////////            }
//////////////        }
//////////////        return byReturn.toString();
//////////////
//////////////
//////////////    }
//////////////    public static final String deCompress(String str)
//////////////    {
//////////////        if (str == null || str.length() == 0)
//////////////        {
//////////////            return str;
//////////////        }
//////////////
//////////////        str = Base64.decode(str);
//////////////        System.out.println("String: " + str);
//////////////        String outputString = "";
////////////////
////////////////        try
////////////////        {
////////////////            boolean nowrap = true;
////////////////
////////////////            // Decompress the bytes
////////////////            Inflater decompresser = new Inflater(nowrap);
////////////////            decompresser.setInput(str.getBytes("UTF-8"), 0, str.length());
////////////////            byte[] result = new byte[10241024];
////////////////            int resultLength = decompresser.inflate(result);
////////////////            decompresser.end();
////////////////
////////////////            // Decode the bytes into a String
////////////////            outputString = new String(result, 0, resultLength, "UTF-8");
////////////////            System.out.println("Inflater(): " + outputString);
////////////////
////////////////        } catch (java.io.UnsupportedEncodingException ex)
////////////////        {
////////////////            // handle
////////////////        } catch (java.util.zip.DataFormatException ex)
////////////////        {
////////////////            // handle
////////////////        }
//////////////
////////////////        return outputString;
//////////////
//////////////        String s1 = null;
//////////////        ByteArrayOutputStream baos = null;
//////////////        
//////////////        try
//////////////        {
//////////////            byte b[] = str.getBytes();
//////////////
//////////////            InputStream bais = new ByteArrayInputStream(b);
//////////////            GZIPInputStream gs = new GZIPInputStream(bais);
//////////////            baos = new ByteArrayOutputStream();
//////////////
//////////////            int numBytesRead = 0;
//////////////            byte[] tempBytes = new byte[6000];
//////////////
//////////////            try
//////////////            {
//////////////                while ((numBytesRead = gs.read(tempBytes, 0, tempBytes.length)) != -1)
//////////////                {
//////////////                    baos.write(tempBytes, 0, numBytesRead);
//////////////                }
//////////////                s1 = new String(baos.toByteArray());
//////////////                System.out.println("String s1: " + s1);
//////////////                s1 = baos.toString();
//////////////
//////////////            } catch (ZipException e)
//////////////            {
//////////////                System.out.println("Fehler beim Entpacken.");
//////////////            }
//////////////        } catch (Exception e)
//////////////        {
//////////////            System.out.println("Exeption beim entpacken");
//////////////            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, e);
//////////////        }
//////////////        
//////////////        System.out.println("Decompressed: " + s1);
//////////////        return s1;
//////////////        
//////////////    }
//////////////
//////////////    public static final String compress(String str)
//////////////    {
//////////////        if (str == null || str.length() == 0)
//////////////        {
//////////////            return str;
//////////////        }
//////////////
//////////////        GZIPOutputStream gzip = null;
//////////////        ByteArrayOutputStream out = null;
//////////////        try
//////////////        {
//////////////            out = new ByteArrayOutputStream();
//////////////            gzip = new GZIPOutputStream(out);
//////////////            gzip.write(str.getBytes());
//////////////
//////////////        } catch (IOException ex)
//////////////        {
//////////////            System.out.println("Fehler beim Packen mit Gzip");
//////////////            Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
//////////////        } finally
//////////////        {
//////////////            try
//////////////            {
//////////////                gzip.close();
//////////////                //return out.toString();
//////////////                return Base64.encode(out.toString());
//////////////
//////////////            } catch (IOException ex)
//////////////            {
//////////////                Logger.getLogger(Gzip.class.getName()).log(Level.SEVERE, null, ex);
//////////////            }
//////////////        }
//////////////        return "";
//////////////    }