package sampledconn

import (
	
	
	
	
	

	manet 
)

const peekSize = 3

type PeekedBytes = [peekSize]byte

var ErrNotTCPConn = errors.New("passed conn is not a TCPConn")

func ( manet.Conn) (PeekedBytes, manet.Conn, error) {
	if ,  := .(ManetTCPConnInterface);  {
		return newWrappedSampledConn()
	}

	return PeekedBytes{}, nil, ErrNotTCPConn
}

type wrappedSampledConn struct {
	ManetTCPConnInterface
	peekedBytes PeekedBytes
	bytesPeeked uint8
}

// tcpConnInterface is the interface for TCPConn's functions
// NOTE: `SyscallConn() (syscall.RawConn, error)` is here to make using this as
// a TCP Conn easier, but it's a potential footgun as you could skipped the
// peeked bytes if using the fallback
type tcpConnInterface interface {
	net.Conn
	syscall.Conn

	CloseRead() error
	CloseWrite() error

	SetLinger(sec int) error
	SetKeepAlive(keepalive bool) error
	SetKeepAlivePeriod(d time.Duration) error
	SetNoDelay(noDelay bool) error
	MultipathTCP() (bool, error)

	io.ReaderFrom
	io.WriterTo
}

type ManetTCPConnInterface interface {
	manet.Conn
	tcpConnInterface
}

func newWrappedSampledConn( ManetTCPConnInterface) (PeekedBytes, *wrappedSampledConn, error) {
	 := &wrappedSampledConn{ManetTCPConnInterface: }
	,  := io.ReadFull(, .peekedBytes[:])
	if  != nil {
		if  == 0 &&  == io.EOF {
			 = io.ErrUnexpectedEOF
		}
		return .peekedBytes, nil, 
	}
	return .peekedBytes, , nil
}

func ( *wrappedSampledConn) ( []byte) (int, error) {
	if int(.bytesPeeked) != len(.peekedBytes) {
		 := copy(, .peekedBytes[.bytesPeeked:])
		.bytesPeeked += uint8()
		return , nil
	}

	return .ManetTCPConnInterface.Read()
}