// Path: src/main/java/com/wizzardo/epoll/readable/ReadableData.java
// public abstract class ReadableData implements Closeable {
// 
//     public ByteBufferWrapper getByteBuffer(ByteBufferProvider bufferProvider) {
//         return bufferProvider.getBuffer();
//     }
// 
//     public void close() throws IOException {
//     }
// 
//     public abstract int read(ByteBuffer byteBuffer);
// 
//     public int read(ByteBufferWrapper wrapper) {
//         return read(wrapper.buffer());
//     }
// 
//     public abstract void unread(int i);
// 
//     public abstract boolean isComplete();
// 
//     public abstract long complete();
// 
//     public abstract long length();
// 
//     public abstract long remains();
// 
//     public boolean hasOwnBuffer() {
//         return false;
//     }
// 
//     public void onComplete() {
//     }
// }


import com.wizzardo.epoll.readable.ReadableData;
import com.wizzardo.tools.http.*;
import com.wizzardo.tools.security.MD5;
import org.junit.Assert;
import org.junit.Test;
import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
            if (read >= image.length / 10) {
                Thread.sleep(2000);
                read = 0;
            }
        }
        Assert.assertEquals(MD5.create().update(image).asString(), MD5.create().update(out.toByteArray()).asString());
//        Thread.sleep(25 * 60 * 1000);

        server.close();
    }

    @Test
    public void testCloseReadable() throws NoSuchAlgorithmException, KeyManagementException {
        int port = 9090;
        final AtomicInteger onClose = new AtomicInteger();
        final AtomicInteger onCloseResource = new AtomicInteger();

        EpollServer server = new EpollServer(port) {
            @Override
            protected IOThread createIOThread(int number, int divider) {
                return new IOThread(number, divider) {
                    @Override
                    public void onDisconnect(Connection connection) {
                        onClose.incrementAndGet();
                    }

                    @Override
                    public void onConnect(Connection connection) {
                        byte[] data = ("HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Length: " + (1024 * 1024 * 1024) + "\r\nContent-Type: image/gif\r\n\r\n").getBytes();
                        connection.write(data, this);
// Path: src/main/java/com/wizzardo/epoll/readable/ReadableData.java
// public abstract class ReadableData implements Closeable {
// 
//     public ByteBufferWrapper getByteBuffer(ByteBufferProvider bufferProvider) {
//         return bufferProvider.getBuffer();
//     }
// 
//     public void close() throws IOException {
//     }
// 
//     public abstract int read(ByteBuffer byteBuffer);
// 
//     public int read(ByteBufferWrapper wrapper) {
//         return read(wrapper.buffer());
//     }
// 
//     public abstract void unread(int i);
// 
//     public abstract boolean isComplete();
// 
//     public abstract long complete();
// 
//     public abstract long length();
// 
//     public abstract long remains();
// 
//     public boolean hasOwnBuffer() {
//         return false;
//     }
// 
//     public void onComplete() {
//     }
// }


// Path: src/test/java/com/wizzardo/epoll/SslServerTest.java
import com.wizzardo.epoll.readable.ReadableData;
import com.wizzardo.tools.http.*;
import com.wizzardo.tools.security.MD5;
import org.junit.Assert;
import org.junit.Test;
import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

            if (read >= image.length / 10) {
                Thread.sleep(2000);
                read = 0;
            }
        }
        Assert.assertEquals(MD5.create().update(image).asString(), MD5.create().update(out.toByteArray()).asString());
//        Thread.sleep(25 * 60 * 1000);

        server.close();
    }

    @Test
    public void testCloseReadable() throws NoSuchAlgorithmException, KeyManagementException {
        int port = 9090;
        final AtomicInteger onClose = new AtomicInteger();
        final AtomicInteger onCloseResource = new AtomicInteger();

        EpollServer server = new EpollServer(port) {
            @Override
            protected IOThread createIOThread(int number, int divider) {
                return new IOThread(number, divider) {
                    @Override
                    public void onDisconnect(Connection connection) {
                        onClose.incrementAndGet();
                    }

                    @Override
                    public void onConnect(Connection connection) {
                        byte[] data = ("HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Length: " + (1024 * 1024 * 1024) + "\r\nContent-Type: image/gif\r\n\r\n").getBytes();
                        connection.write(data, this);
                        connection.write(new ReadableData() {