package tcpreuse

import (
	
	
	

	
	manet 
)

// This is reading the first 3 bytes of the first packet after the handshake.
// It's set to the default TCP connect timeout in the TCP Transport.
//
// A var so we can change it in tests.
var identifyConnTimeout = 5 * time.Second

type DemultiplexedConnType int

const (
	DemultiplexedConnType_Unknown DemultiplexedConnType = iota
	DemultiplexedConnType_MultistreamSelect
	DemultiplexedConnType_HTTP
	DemultiplexedConnType_TLS
)

func ( DemultiplexedConnType) () string {
	switch  {
	case DemultiplexedConnType_MultistreamSelect:
		return "MultistreamSelect"
	case DemultiplexedConnType_HTTP:
		return "HTTP"
	case DemultiplexedConnType_TLS:
		return "TLS"
	default:
		return fmt.Sprintf("Unknown(%d)", int())
	}
}

func ( DemultiplexedConnType) () bool {
	return  >= 1 ||  <= 3
}

// identifyConnType attempts to identify the connection type by peeking at the
// first few bytes.
// Its Callers must not use the passed in Conn after this function returns.
// If an error is returned, the connection will be closed.
func identifyConnType( manet.Conn) (DemultiplexedConnType, manet.Conn, error) {
	if  := .SetReadDeadline(time.Now().Add(identifyConnTimeout));  != nil {
		 := .Close()
		return 0, nil, errors.Join(, )
	}

	, ,  := sampledconn.PeekBytes()
	if  != nil {
		 := .Close()
		return 0, nil, errors.Join(, )
	}

	if  := .SetReadDeadline(time.Time{});  != nil {
		 := .Close()
		return 0, nil, errors.Join(, )
	}

	if IsMultistreamSelect() {
		return DemultiplexedConnType_MultistreamSelect, , nil
	}
	if IsTLS() {
		return DemultiplexedConnType_TLS, , nil
	}
	if IsHTTP() {
		return DemultiplexedConnType_HTTP, , nil
	}
	return DemultiplexedConnType_Unknown, , nil
}

// Matchers are implemented here instead of in the transports so we can easily fuzz them together.
type Prefix = [3]byte

func ( Prefix) bool {
	return string([:]) == "\x13/m"
}

func ( Prefix) bool {
	switch string([:]) {
	case "GET", "HEA", "POS", "PUT", "DEL", "CON", "OPT", "TRA", "PAT":
		return true
	default:
		return false
	}
}

func ( Prefix) bool {
	switch string([:]) {
	case "\x16\x03\x01", "\x16\x03\x02", "\x16\x03\x03":
		return true
	default:
		return false
	}
}