/*
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (C) 2018 National Library of Australia and the jwarc contributors
 */

package org.netpreserve.jwarc;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import java.util.concurrent.atomic.AtomicLong;

public class WarcWriter {
    private final WritableByteChannel channel;
    private final WarcCompression compression;
    private final ByteBuffer buffer = ByteBuffer.allocate(8192);
    ByteBuffer recordSeperator = ByteBuffer.allocate(2);
    
    private AtomicLong bytesWritten = new AtomicLong(0);

    public WarcWriter(WritableByteChannel channel, WarcCompression compression) {
        if (compression == WarcCompression.GZIP) {
            throw new UnsupportedOperationException("Writing of GZIP WARC files is not currently supported");
        }
        this.channel = channel;
        this.compression = compression;
        
        recordSeperator.put(new byte[] { '\n','\n' });
    }

    public synchronized void write(WarcRecord record) throws IOException {
        // TODO: buffer headers, compression
        bytesWritten.addAndGet(channel.write(ByteBuffer.wrap(record.serializeHeader())));
        MessageBody body = record.body();
        while (body.read(buffer) >= 0) {
            buffer.flip();
            bytesWritten.addAndGet(channel.write(buffer));
            buffer.compact();
        }
        recordSeperator.rewind();
        bytesWritten.addAndGet(channel.write(recordSeperator));
                
    }
    
    public long getCurrentWritePosition() {
        return bytesWritten.get();
    }
}

@@ -207,16 +207,62 @@
 Buffer;%0A
+import java.nio.channels.SeekableByteChannel;%0A
 import j
@@ -347,16 +347,105 @@
 cLong;%0A%0A
+/**%0A * Writes records to a WARC file.%0A * %3Cp/%3E%0A * Compression is not yet implemented.%0A */%0A
 public c
@@ -706,27 +706,23 @@
 micLong 
-bytesWritte
+positio
 n = new 
@@ -816,16 +816,35 @@
 ression)
+ throws IOException
  %7B%0A     
@@ -1081,24 +1081,16 @@
 ession;%0A
-        
 %0A       
@@ -1136,16 +1136,151 @@
 '%5Cn' %7D);
+%0A%0A        if (channel instanceof SeekableByteChannel) %7B%0A            position.set(((SeekableByteChannel) channel).position());%0A        %7D
 %0A    %7D%0A%0A
@@ -1403,35 +1403,31 @@
 ion%0A        
-bytesWritte
+positio
 n.addAndGet(
@@ -1603,35 +1603,31 @@
             
-bytesWritte
+positio
 n.addAndGet(
@@ -1732,27 +1732,23 @@
         
-bytesWritte
+positio
 n.addAnd
@@ -1811,45 +1811,278 @@
   %7D%0A
+%0A
     
+/**
 %0A    
-public long g
+ * Returns the byte position the next record will be written to.%0A     *%0A     * If the underlying channel is not seekable the r
 et
-C
 ur
-rentWriteP
+ned value will be relative to the position the channel%0A     * was in when the WarcWriter was created.%0A     */%0A    public long p
 osit
@@ -2108,19 +2108,15 @@
 urn 
-bytesWritte
+positio
 n.ge

Change position() to better match WarcReader