package hh.dejsem.net;

import android.net.Uri;
import android.support.v4.provider.DocumentFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import hh.lib.D;

/**
 * file I/O interface
 */
public class FileIO implements GetPut {
	D d;
	FileChannel fc = null;
	// ----------------------------------------------------------

	public FileIO(D d, DocumentFile parentDf, File f, String mode) throws Exception {    // pro nový file na SD card
		this.d = d.klon(this);
		if(!mode.equals("r")) {
			Uri dfUri = parentDf.createFile("application/octet-stream", f.getName()).getUri();
			fc = ((FileOutputStream)(d.getAct().getContentResolver().openOutputStream(dfUri))).getChannel();
			if(this.d.ll(4)) this.d.l("created, file path=" + f.getAbsolutePath());
		}
		else fc = new RandomAccessFile(f, mode).getChannel();
	}

	public FileIO(D d, File f, String mode) throws Exception {
		this.d = d.klon(this);
		fc = new RandomAccessFile(f, mode).getChannel();
		if(d.ll(4) && mode.equals("rw")) this.d.l("created, file path=" + f.getAbsolutePath());
	}

	public boolean get(ByteBuffer buf) throws Exception {
		if(d.ll(5)) d.l("get from file, buf=" + D.bufStat(buf));
		try { while(buf.hasRemaining()) if(fc.read(buf) < 0) break; }
		catch(Exception x) { close(); throw new Exception("file channel read", x); };
		if(d.ll(5)) d.l("" + buf.position()+ " read");
		return buf.position() > 0;
	}

	public int put(ByteBuffer buf) throws Exception {
		int n = 0;
		if(d.ll(5)) d.l("output to file, buf=" + D.bufStat(buf));
		while(buf.hasRemaining()) {
			n = 0;
			try { n = fc.write(buf); }
			catch(Exception x) { close(); throw new Exception("file channel write", x); }
			if(d.ll(5)) d.l("" + n + " written"); }
		buf.clear();
		return n;
	}

	public void close() {
		try { fc.close(); }
		catch(IOException e) { d.l("close file channel" + e.getMessage()); }
	}
}
