package net.argius.filetool;

import java.io.*;

/**
 * ファイル圧縮処理。
 */
public final class FileCompressor {

    /**
     * ファイルを圧縮する。
     * 出力先ファイルは、元ファイルに圧縮タイプの拡張子を付加したものになる。
     * @param src 圧縮対象ファイル
     * @param type 圧縮タイプ
     * @throws IOException 入出力エラーが発生した場合 
     */
    public static void compress(File src, CompressType type) throws IOException {
        File dst;
        if (type == CompressType.GZIP) {
            dst = new File(src.getParentFile(), src.getName() + ".gz");
        } else if (type == CompressType.BZIP2) {
            dst = new File(src.getParentFile(), src.getName() + ".bz2");
        } else {
            throw new IllegalArgumentException();
        }
        compress(src, dst, type);
    }

    /**
     * ファイルを圧縮する。
     * 圧縮タイプは、出力先の拡張子から判別する。
     * @param src 圧縮対象ファイル
     * @param dst 出力先ファイル
     * @throws IOException 入出力エラーが発生した場合 
     */
    public static void compress(File src, File dst) throws IOException {
        compress(src, dst, CompressType.getType(dst));
    }

    /**
     * ファイルを圧縮する。
     * @param src 圧縮対象ファイル
     * @param dst 出力先ファイル
     * @param type 圧縮タイプ
     * @throws IOException 入出力エラーが発生した場合 
     */
    public static void compress(File src, File dst, CompressType type) throws IOException {
        File tmp = Utilities.createTemporaryFile();
        Compressor compressor;
        if (type == CompressType.GZIP) {
            compressor = new GzipCompressor(new FileOutputStream(tmp));
        } else if (type == CompressType.BZIP2) {
            compressor = new Bzip2Compressor(new FileOutputStream(tmp));
        } else {
            throw new IllegalArgumentException();
        }
        try {
            InputStream is = new FileInputStream(src);
            try {
                compressor.compress(is);
            } finally {
                is.close();
            }
        } finally {
            compressor.close();
        }
        IOUtilities.move(tmp, dst, false);
    }

    /**
     * 使い方の表示。
     */
    private static void printUsage() {
        PrintStream err = System.err;
        err.println("FileCompressor (argius-filetool)");
        err.println("usage : (command) src dst");
        err.println("options: none");
    }

    /**
     * FileCompressorの実行。
     * @param args パラメータ(see 'usage')
     */
    public static void main(String[] args) {
        if (args.length < 2) {
            printUsage();
            return;
        }
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            if (arg.equals("-h") || arg.equals("--help")) {
                printUsage();
                return;
            }
        }
        final String commandNameInfo = "FileCompressor: ";
        int status;
        try {
            FileCompressor.compress(new File(args[0]), new File(args[1]));
            status = 0;
        } catch (IOException ex) {
            System.out.println(commandNameInfo + ex.getMessage());
            status = 1;
        } catch (Exception ex) {
            String message = ex + Utilities.getFirstStackTrace(ex, DiskUsage.class);
            System.out.println(commandNameInfo + message);
            status = 255;
        }
        if (status > 0) {
            System.exit(status);
        }
    }

}
