package com.fp.common.files;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import org.apache.velocity.exception.ResourceNotFoundException;

/**
 * Clase utilitaria que se encarga del manejo de streams.
 * 
 * @author Jorge Vaca.
 * @version 2.1
 */
public class StreamHelper {
    public static void serialize(Object pData, String pName) throws IOException {
        FileOutputStream sw = new FileOutputStream("/log/" + pName + ".rq");
        ObjectOutputStream oo = new ObjectOutputStream(sw);
        oo.writeObject(pData);
        oo.close();
    }

    public static String readResource(String pResource) throws Exception {
        InputStream in = String.class.getResourceAsStream(pResource);
        try {
            if (in == null) {
                throw new ResourceNotFoundException(pResource);
            }
            return StreamHelper.readStream(in);
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    public static byte[] objectToBytes(Object pData) throws IOException {
        ByteArrayOutputStream sw = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(sw);
        oo.writeObject(pData);
        oo.close();
        return sw.toByteArray();
    }

    public static Object bytesToObject(byte[] pData) throws IOException, ClassNotFoundException {
        ByteArrayInputStream sw = new ByteArrayInputStream(pData);
        ObjectInputStream oo = new ObjectInputStream(sw);
        Object data = oo.readObject();
        oo.close();
        return data;
    }

    public static Object deserialize(String pName) throws IOException, ClassNotFoundException {
        FileInputStream sw = new FileInputStream("/log/" + pName + ".rq");
        ObjectInputStream oo = new ObjectInputStream(sw);
        Object data = oo.readObject();
        oo.close();
        return data;
    }

    public static String readFile(String pPath) throws IOException {
        FileInputStream fin = new FileInputStream(pPath);
        String data = StreamHelper.readStream(fin);
        fin.close();
        return data;
    }

    public static void saveFile(String pPath, byte[] pContent) throws IOException {
        FileOutputStream fout = new FileOutputStream(pPath);
        fout.write(pContent);
        fout.close();
    }

    public static String readStream(InputStream pIn) throws IOException {
        byte b[] = new byte[9999];
        int car = 0;
        String data = "";
        do {
            car = pIn.read(b);
            if (car > 0) {
                data += new String(b, 0, car);
            }
        } while (car > 0);
        return data;
    }

    public static void writeFile(String pPath, String pData) throws IOException {
        FileOutputStream fos = new FileOutputStream(pPath);
        fos.write(pData.getBytes());
        fos.close();
    }

    public static byte[] compress64k(byte[] pData) throws IOException {
        byte[] output = new byte[65536];
        Deflater compresser = new Deflater();
        compresser.setInput(pData);
        compresser.finish();
        int c = compresser.deflate(output);
        ByteArrayInputStream by = new ByteArrayInputStream(output, 0, c);
        byte b[] = StreamHelper.streamToBytes(by);
        by.close();
        return b;
    }

    public static byte[] unCompress64k(byte[] pData) throws IOException, DataFormatException {
        Inflater decompresser = new Inflater();
        decompresser.setInput(pData, 0, pData.length);
        byte[] result = new byte[65536];
        int resultLength = decompresser.inflate(result);
        decompresser.end();
        ByteArrayInputStream by = new ByteArrayInputStream(result, 0, resultLength);
        byte b[] = StreamHelper.streamToBytes(by);
        by.close();
        return b;
    }

    public static byte[] compress(byte[] pData) throws IOException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DeflaterOutputStream dout = new DeflaterOutputStream(bout);
        dout.write(pData);
        dout.close();
        byte b[] = bout.toByteArray();
        return b;
    }

    public static byte[] unCompress(byte[] pData) throws IOException {
        ByteArrayInputStream bin = new ByteArrayInputStream(pData);
        InflaterInputStream din = new InflaterInputStream(bin);
        byte b[] = StreamHelper.streamToBytes(din);
        din.close();

        return b;
    }

    public static byte[] streamToBytes(InputStream pData) throws IOException {
        ByteArrayOutputStream by = new ByteArrayOutputStream();
        byte b[] = new byte[9999];
        int car = 0;
        do {
            car = pData.read(b);
            if (car > 0) {
                by.write(b, 0, car);
            }
        } while (car > 0);
        b = by.toByteArray();
        by.close();
        return b;
    }

    public static byte[] compress(String pData) throws IOException {
        return StreamHelper.compress(pData.getBytes());
    }

    public static byte[] compressObject(Object pData) throws IOException {
        return StreamHelper.compress(StreamHelper.objectToBytes(pData));
    }

    public static String unCompressToString(byte[] pData) throws IOException {
        byte[] b = StreamHelper.unCompress(pData);
        return new String(b);
    }

    public static Object unCompressToObject(byte[] pData) throws IOException, ClassNotFoundException {
        byte[] b = StreamHelper.unCompress(pData);
        return StreamHelper.bytesToObject(b);
    }

}
