package com.brilliance.mda.runtime.mda.util;

import java.io.*;
import java.util.List;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Archives {
    private static final Logger log = LoggerFactory.getLogger(Archives.class);

    private static void archive(File file, ArchiveOutputStream aos, String entryName)
            throws IOException {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files.length < 1) {
                aos.putArchiveEntry(aos.createArchiveEntry(file, entryName));
                aos.closeArchiveEntry();
            }
            for (File _file : files)
                archive(_file, aos, entryName + "/" + _file.getName());
        } else {
            aos.putArchiveEntry(aos.createArchiveEntry(file, entryName));
            FileInputStream fis = new FileInputStream(file);
            IOUtils.copyLarge(fis, aos);
            fis.close();
            aos.closeArchiveEntry();
        }
    }

    public static void archive(OutputStream os, String[] fileNames, String baseDirectoryName) {
        ZipArchiveOutputStream zos = null;
        try {
            zos = new ZipArchiveOutputStream(os);
            File baseDirectory = baseDirectoryName == null ? null : new File(baseDirectoryName);
            for (String fileName : fileNames)
                archive(baseDirectory == null ? new File(fileName) : new File(baseDirectory, fileName), zos, fileName);
        } catch (Exception e) {
            log.error("Archive to zip package error.", e);
        }
        MdaUtils.closeQuietly(zos);
    }

    public static void archive(OutputStream os, List<String> fileNames, File baseDirectory) {
        ZipArchiveOutputStream zos = null;
        try {
            zos = new ZipArchiveOutputStream(os);
            for (String fileName : fileNames)
                archive(baseDirectory == null ? new File(fileName) : new File(baseDirectory, fileName), zos, fileName);
        } catch (Exception e) {
            log.error("Archive to zip package error.", e);
        }
        MdaUtils.closeQuietly(zos);
    }

    public static boolean extract(InputStream is, String entryName, OutputStream os) {
        boolean flag = false;
        ZipArchiveInputStream zis = null;
        try {
            zis = new ZipArchiveInputStream(is);
            do {
                ArchiveEntry entry = zis.getNextEntry();
                if (entry == null)
                    break;
                if ((entryName == null) || (!entryName.equals(entry.getName())))
                    continue;
                flag = true;
                IOUtils.copyLarge(zis, os, 0L, entry.getSize());
            }
            while (!flag);
        } catch (Exception e) {
            log.error("Extract file form zip package error.", e);
        }
        MdaUtils.closeQuietly(zis);
        return flag;
    }


}
