package com.ygtx.emcs.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.*;

public class TimeoutBufferedReader {

    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final BufferedReader reader;
    private final long timeout;

    public TimeoutBufferedReader(InputStream in, long timeout, TimeUnit unit) {
        this.reader = new BufferedReader(new InputStreamReader(in));
        this.timeout = unit.toNanos(timeout);
    }

    public String readLine(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        Future<String> future = executor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return reader.readLine();
            }
        });

        try {
            return future.get(timeout, unit);
        } catch (TimeoutException e) {
            future.cancel(true); // may interrupt if the task has not finished
            throw e;
        } finally {
            executor.shutdownNow(); // cancel any pending tasks
        }
    }

    public void close() {
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        executor.shutdown();
    }
}