package com.sf.vertx.utils;

import java.util.concurrent.atomic.AtomicBoolean;

import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.streams.ReadStream;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Filter implements ReadStream<Buffer> {

	private final AtomicBoolean paused = new AtomicBoolean();
	private ReadStream<Buffer> stream;
	private Buffer expected = Buffer.buffer();
	private Handler<Buffer> dataHandler;
	private Handler<Throwable> exceptionHandler;
	private Handler<Void> endHandler;

	/***
	 * 
	 * @param s
	 * @param encryption true: 请求参数解密, false: 返回数据 加密
	 * @return
	 */
	public ReadStream<Buffer> init(String uri, ReadStream<Buffer> s, Boolean encryption) {
		stream = s;
		stream.handler(buff -> {
			if (dataHandler != null) {
				byte[] bytes = new byte[buff.length()];
				for (int i = 0; i < bytes.length; i++) {
					// bytes[i] = (byte) (('a' - 'A') + buff.getByte(i));
					bytes[i] = (byte) (buff.getByte(i));
				}

				String res = new String(bytes);
				log.info("request uri:{}, return data:{}", uri, res);
				expected.appendBytes(bytes);
				dataHandler.handle(Buffer.buffer(bytes));
			}
		});
		stream.exceptionHandler(err -> {
			if (exceptionHandler != null) {
				exceptionHandler.handle(err);
			}
		});
		stream.endHandler(v -> {
			if (endHandler != null) {
				endHandler.handle(v);
			}
		});
		return this;
	}

	@Override
	public ReadStream<Buffer> pause() {
		paused.set(true);
		stream.pause();
		return this;
	}

	@Override
	public ReadStream<Buffer> resume() {
		stream.resume();
		return this;
	}

	@Override
	public ReadStream<Buffer> fetch(long amount) {
		stream.fetch(amount);
		return this;
	}

	@Override
	public ReadStream<Buffer> exceptionHandler(Handler<Throwable> handler) {
		exceptionHandler = handler;
		return this;
	}

	@Override
	public ReadStream<Buffer> handler(Handler<Buffer> handler) {
		dataHandler = handler;
		return this;
	}

	@Override
	public ReadStream<Buffer> endHandler(Handler<Void> handler) {
		endHandler = handler;
		return this;
	}
}