package org.zeroxlab.momodict.archive;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.io.FileUtils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import rx.functions.Action0;

public class TarExtractor implements Extractor {

    @Override
    public FileSet extract(final File outputDir, InputStream inputStream) throws Exception {
        FileSet archive = new FileSet();
        archive.setCleanCallback(new Action0() {
            @Override
            public void call() {
                try {
                    if (outputDir.isDirectory()) {
                        FileUtils.deleteDirectory(outputDir);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        TarArchiveInputStream tis = new TarArchiveInputStream(inputStream);
        while (tis.getNextEntry() != null) {
            onEntryFound(outputDir, tis, tis.getCurrentEntry(), archive);
        }

        if (!archive.isSane()) {
            throw new Exception("RealmBook is malformed");
        }
        return archive;
    }

    private void onEntryFound(File parent,
                              InputStream is,
                              TarArchiveEntry entry,
                              FileSet archive)
            throws Exception {

        final String fileName = entry.getName();
        if (entry.isDirectory()) {
            File dir = new File(parent, fileName);
            if (!dir.mkdirs()) {
                throw new Exception("Create dir fail");
            }
        } else {
            // TODO: support .dz file. issue #2
            if (fileName.endsWith(".dz")) {
                StringBuilder msg = new StringBuilder();
                msg.append("Haven't support .dz (dictzip) file so far.\n");
                msg.append("please provide '.dict' to instead of '.dict.dz'");
                throw new RuntimeException(msg.toString());
            }
            // write file
            File out = new File(parent, fileName);

            byte[] buf = new byte[65535];
            FileOutputStream fos = new FileOutputStream(out);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            int count;
            while ((count = is.read(buf)) != -1) {
                bos.write(buf, 0, count);
            }
            bos.close();

            // cache file path
            if (fileName.endsWith(".idx")) {
                archive.set(FileSet.Type.IDX, out.getAbsolutePath());
            } else if (fileName.endsWith(".ifo")) {
                archive.set(FileSet.Type.IFO, out.getAbsolutePath());
            } else if (fileName.endsWith(".dict.dz") || fileName.endsWith(".dict")) {
                archive.set(FileSet.Type.DICT, out.getAbsolutePath());
            }
        }
        System.out.println(entry.getName());
    }
}

@@ -167,24 +167,103 @@
 nputStream;%0A
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;%0A
 import org.a
@@ -290,16 +290,16 @@
 eUtils;%0A
-
 %0Aimport 
@@ -349,16 +349,48 @@
 o.File;%0A
+import java.io.FileInputStream;%0A
 import j
@@ -1907,386 +1907,8 @@
 e %7B%0A
-            // TODO: support .dz file. issue #2%0A            if (fileName.endsWith(%22.dz%22)) %7B%0A                StringBuilder msg = new StringBuilder();%0A                msg.append(%22Haven't support .dz (dictzip) file so far.%5Cn%22);%0A                msg.append(%22please provide '.dict' to instead of '.dict.dz'%22);%0A                throw new RuntimeException(msg.toString());%0A            %7D%0A
     
@@ -2635,12 +2635,734 @@
 dz%22)
- %7C%7C 
+) %7B%0A                // found a dz file, use gzip to extract again%0A                String extractFileName = out.getAbsolutePath().replace(%22.dict.dz%22, %22.dict%22);%0A                FileInputStream fis = new FileInputStream(out);%0A                GzipCompressorInputStream gis = new GzipCompressorInputStream(fis);%0A                FileOutputStream fos2 = new FileOutputStream(extractFileName);%0A                byte%5B%5D buffer = new byte%5B2048%5D;%0A                int r = 0;%0A                while ((r = gis.read(buffer))!= -1) %7B%0A                    fos2.write(buffer, 0, r);%0A                %7D%0A                fis.close();%0A                fos2.close();%0A                archive.set(FileSet.Type.DICT, extractFileName);%0A            %7D else if (
 file

fix #2: extract dz file by using Gzip stream