package com.bunker.icache;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;

public class FileCacheable extends LoadWaitCacheable {
	private String mFileName;
	private final String mPath;
	private static final int BUFFER_SIZE = 1024;//10mb
	private FileSemaphore mSemaphore;

	public FileCacheable(String path) {
		mPath = path;
		mSemaphore = new FileSemaphore();
	}

	@Override
	public byte[] cachingBytes() {
		InputStream input = cachingStream();
		if (input == null) {
			return null;
		}

		try {
			ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
			byte []readTemp = new byte [BUFFER_SIZE];
			int readSize = 0;
			while ((readSize = input.read(readTemp)) > 0) {
				byteBuffer.write(readTemp, 0, readSize);
			}
			input.close();
			return byteBuffer.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public InputStream cachingStream() {
		if (!waitLoad())
			return null;

		if (!mSemaphore.counting())
			return null;

		try {
			return new SemaphoreInputStream(new FileInputStream(new File(getFileName())), mSemaphore);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		mSemaphore.discounting();
		return null;
	}

	@Override
	public boolean registerCacheBytes(byte[] bytes) {
		try {
			FileOutputStream outputStream = new FileOutputStream(makeUniqueFile());
			outputStream.write(bytes);
			outputStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		mSemaphore.initSemaphore(getFileName());
		return super.registerCacheBytes(bytes);
	}

	@Override
	public boolean registerCacheStream(InputStream stream) {
		try {
			byte []buffer = new byte[BUFFER_SIZE];
			FileOutputStream fout = new FileOutputStream(makeUniqueFile());
			int readSize = 0;

			while ((readSize = stream.read(buffer)) > 0) {
				fout.write(buffer, 0, readSize);
			}
			fout.close();
			stream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		mSemaphore.initSemaphore(getFileName());
		return super.registerCacheStream(stream);
	}

	private File makeUniqueFile() {
		mFileName = Calendar.getInstance().getTimeInMillis() + "";
		return new File(getFileName());
	}

	private String getFileName() {
		return mPath + mFileName;
	}

	@Override
	public boolean remove() {
		mSemaphore.setRemoveTrigger();
		return true;
	}

	@Override
	public long getCacheSize() {
		if (!isLoaded())
			return 0;

		File file = new File(getFileName());
		return (int) file.length();
	}
}