package com.sprylab.xar.writer;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.zip.Deflater;

import com.sprylab.xar.toc.model.ChecksumAlgorithm;
import com.sprylab.xar.toc.model.Encoding;
import com.sprylab.xar.utils.HashUtils;

import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.DeflaterSink;
import okio.Okio;
import okio.Source;

public class XarFileSource implements XarSource {

    private Buffer buffer = new Buffer();

    private File file;

    private Encoding encoding;

    private ChecksumAlgorithm checksumStyle = ChecksumAlgorithm.NONE;

    private String extractedChecksum;

    private String archivedChecksum;

    public XarFileSource(final File file) throws IOException {
        this(file, Encoding.NONE);
    }

    public XarFileSource(final File file, final Encoding encoding) throws IOException {
        this(file, encoding, ChecksumAlgorithm.NONE);
    }

    public XarFileSource(final File file, final Encoding encoding, final ChecksumAlgorithm checksumStyle) throws IOException {
        this.file = file;
        this.encoding = encoding;
        this.checksumStyle = checksumStyle;
        final BufferedSource fileSource = Okio.buffer(Okio.source(file));
        fileSource.require(file.length());
        this.extractedChecksum = HashUtils.hashHex(fileSource, checksumStyle);
        switch (encoding) {
            case NONE:
                this.buffer.writeAll(fileSource);
                this.archivedChecksum = extractedChecksum;
                break;
            case GZIP:
                try (BufferedSource input = Okio.buffer(Okio.source(file));
                     BufferedSink output = Okio.buffer(new DeflaterSink(this.buffer, new Deflater()))) {
                    output.writeAll(input);
                    output.close();
                    this.archivedChecksum = HashUtils.hashHex(this.buffer, checksumStyle);
                }
                break;
            case BZIP2:
                throw new UnsupportedEncodingException("Encoding not supported: " + encoding.name());
        }
    }

    @Override
    public long getLength() {
        return buffer.size();
    }

    @Override
    public ChecksumAlgorithm getChecksumAlgorithm() {
        return checksumStyle;
    }

    @Override
    public Encoding getEncoding() {
        return encoding;
    }

    @Override
    public Source getSource() {
        return buffer;
    }

    @Override
    public String getName() {
        return file.getName();
    }

    @Override
    public long getSize() {
        return file.length();
    }

    @Override
    public long getLastModified() {
        return file.lastModified();
    }

    @Override
    public String getExtractedChecksum() {
        return extractedChecksum;
    }

    @Override
    public String getArchivedChecksum() {
        return archivedChecksum;
    }
}

@@ -1218,16 +1218,21 @@
         
+try (
 final Bu
@@ -1279,34 +1279,37 @@
 io.source(file))
-;%0A
+) %7B%0A%09
         fileSour
@@ -1331,24 +1331,25 @@
 .length());%0A
+%09
         this
@@ -1407,32 +1407,33 @@
 checksumStyle);%0A
+%09
         switch (
@@ -1440,24 +1440,25 @@
 encoding) %7B%0A
+%09
             
@@ -1468,16 +1468,17 @@
 e NONE:%0A
+%09
         
@@ -1515,24 +1515,25 @@
 ileSource);%0A
+%09
             
@@ -1575,24 +1575,25 @@
 edChecksum;%0A
+%09
             
@@ -1595,32 +1595,33 @@
          break;%0A
+%09
             case
@@ -1627,16 +1627,17 @@
 e GZIP:%0A
+%09
         
@@ -1653,84 +1653,8 @@
 ry (
-BufferedSource input = Okio.buffer(Okio.source(file));%0A                     
 Buff
@@ -1729,24 +1729,25 @@
 ater()))) %7B%0A
+%09
             
@@ -1774,16 +1774,22 @@
 All(
-input
+fileSource
 );%0A
+%09
     
@@ -1816,24 +1816,25 @@
 ut.close();%0A
+%09
             
@@ -1912,16 +1912,17 @@
 Style);%0A
+%09
         
@@ -1927,24 +1927,25 @@
           %7D%0A
+%09
             
@@ -1955,16 +1955,17 @@
  break;%0A
+%09
         
@@ -1980,16 +1980,17 @@
  BZIP2:%0A
+%09
         
@@ -2083,16 +2083,27 @@
 ame());%0A
+%09        %7D%0A
         

Fix resource flushing and cleanup when adding files to xar archives