package org.apollo.update;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;

import java.io.IOException;
import java.nio.ByteBuffer;

import org.apollo.fs.FileDescriptor;
import org.apollo.fs.IndexedFileSystem;
import org.apollo.net.codec.update.OnDemandRequest;
import org.apollo.net.codec.update.OnDemandResponse;

/**
 * A worker which services 'on-demand' requests.
 * 
 * @author Graham
 */
public final class OnDemandRequestWorker extends RequestWorker<OnDemandRequest, IndexedFileSystem> {

	/**
	 * The maximum length of a chunk, in bytes.
	 */
	private static final int CHUNK_LENGTH = 500;

	/**
	 * Creates the 'on-demand' request worker.
	 * 
	 * @param dispatcher The dispatcher.
	 * @param fs The file system.
	 */
	public OnDemandRequestWorker(UpdateDispatcher dispatcher, IndexedFileSystem fs) {
		super(dispatcher, fs);
	}

	@Override
	protected ChannelRequest<OnDemandRequest> nextRequest(UpdateDispatcher dispatcher) throws InterruptedException {
		return dispatcher.nextOnDemandRequest();
	}

	@Override
	protected void service(IndexedFileSystem fs, Channel channel, OnDemandRequest request) throws IOException {
		FileDescriptor desc = request.getFileDescriptor();

		ByteBuffer buffer = fs.getFile(desc);
		int length = buffer.remaining();

		for (int chunk = 0; buffer.remaining() > 0; chunk++) {
			int chunkSize = buffer.remaining();
			if (chunkSize > CHUNK_LENGTH) {
				chunkSize = CHUNK_LENGTH;
			}

			byte[] tmp = new byte[chunkSize];
			buffer.get(tmp, 0, tmp.length);
			ByteBuf chunkData = Unpooled.wrappedBuffer(tmp, 0, chunkSize);

			OnDemandResponse response = new OnDemandResponse(desc, length, chunk, chunkData);
			channel.writeAndFlush(response);
		}
	}

}
@@ -152,73 +152,8 @@
 on;%0A
-import java.nio.ByteBuffer;%0A%0Aimport org.apollo.fs.FileDescriptor;
 %0Aimp
@@ -519,20 +519,28 @@
 unk, in 
+%7B@code 
 byte
+%7D
 s.%0A%09 */%0A
@@ -1124,97 +1124,87 @@
 %7B%0A%09%09
-FileDescriptor desc = request.getFileDescriptor();%0A%0A%09%09ByteBuffer buffer = fs.getFile(desc
+ByteBuf buffer = Unpooled.wrappedBuffer(fs.getFile(request.getFileDescriptor())
 );%0A%09
@@ -1222,31 +1222,35 @@
  = buffer.re
-maining
+adableBytes
 ();%0A%0A%09%09for (
@@ -1273,23 +1273,27 @@
 uffer.re
-maining
+adableBytes
 () %3E 0; 
@@ -1326,320 +1326,179 @@
 e = 
-buffer.remaining();%0A%09%09%09if (chunkSize %3E CHUNK_LENGTH) %7B%0A%09%09%09%09chunkSize = CHUNK_LENGTH;%0A%09%09%09%7D%0A%0A%09%09%09byte%5B%5D tmp = new byte%5BchunkSize%5D;%0A%09%09%09buffer.get(tmp, 0, tmp.length);%0A%09%09%09ByteBuf chunkData = Unpooled.wrappedBuffer(tmp, 0, chunkSize);%0A%0A%09%09%09OnDemandResponse response = new OnDemandResponse(desc, length, chunk, chunkData
+Math.min(buffer.readableBytes(), CHUNK_LENGTH);%0A%09%09%09OnDemandResponse response = new OnDemandResponse(request.getFileDescriptor(), length, chunk, buffer.readBytes(chunkSize)
 );%0A%09

Rebase OnDemandRequestWorker#service(T, Channel, V)