// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package nettest

import (
	
	
	
	
)

// Listener is an in-memory test implementation of net.Listener.
type Listener struct {
	gate      gate.Gate
	queue     queue[*Conn]
	closed    bool
	acceptErr error
	closeErr  error

	addr     net.Addr
	nextaddr netip.AddrPort
}

// NewListener returns a new Listener.
func () *Listener {
	return &Listener{
		gate:     gate.New(false),
		addr:     net.TCPAddrFromAddrPort(netip.MustParseAddrPort("192.0.2.1:1000")),
		nextaddr: netip.MustParseAddrPort("192.0.2.1:10001"),
	}
}

// Close closes the listener.
// Any blocked Accept operations will be unblocked and return errors.
func ( *Listener) () error {
	.lock()
	defer .unlock()
	 := .closeErr
	.closed = true
	.acceptErr = net.ErrClosed
	.closeErr = net.ErrClosed
	if  != nil {
		return &net.OpError{
			Op:   "close",
			Net:  "tcp",
			Addr: .addr,
			Err:  ,
		}
	}
	return 
}

// Addr returns the listener's network address.
//
// The address is always a *net.TCPAddr.
func ( *Listener) () net.Addr {
	.lock()
	defer .unlock()
	return .addr
}

// SetAddr sets the listener's network address.
func ( *Listener) ( net.Addr) {
	.lock()
	defer .unlock()
	.addr = 
}

// NewConn returns a new connection to the listener.
//
// Accept will return the other side of the conn.
func ( *Listener) () *Conn {
	return .NewConnConfig(func(*Conn) {})
}

// NewConnConfig returns a new connection to the listener.
//
// The function f is called with the new client connection.
// After f returns, Accept will return the other side of the connection.
//
// For example, to create a connection from a specific IP address:
//
//	conn := li.NewConnConfig(func(conn *nettest.Conn) {
//		conn.SetLocalAddr(net.TCPAddrFromAddrPort(netip.MustParseAddrPort("10.0.0.1:1234")))
//	})
func ( *Listener) ( func(*Conn)) *Conn {
	.lock()
	defer .unlock()
	,  := newConnPair(
		net.TCPAddrFromAddrPort(.nextaddr),
		.addr,
	)
	.nextaddr = netip.AddrPortFrom(.nextaddr.Addr(), .nextaddr.Port()+1)
	()
	.queue.push()
	return 
}

// Accept waits for and returns the next connection to the listener.
//
// The connections returned by Accept are always [*Conn]s.
func ( *Listener) () (net.Conn, error) {
	.gate.WaitAndLock(context.Background())
	defer .unlock()
	if .acceptErr != nil && .queue.len() == 0 {
		return nil, &net.OpError{
			Op:   "accept",
			Net:  "tcp",
			Addr: .addr,
			Err:  .acceptErr,
		}
	}
	return .queue.pop(), nil
}

// SetAcceptError causes any currently blocked and future Accept calls to return
// a net.OpError wrapping err.
// Accept will return any available connections before returning the error,
// including connections created after the error is set.
// A nil error restores the usual behavior.
func ( *Listener) ( error) {
	.gate.Lock()
	defer .unlock()
	if !.closed {
		.acceptErr = 
	}
}

// SetCloseError sets the error returned by Close.
// Close still closes the listener.
// A nil error restores the usual behavior.
func ( *Listener) ( error) {
	.gate.Lock()
	defer .unlock()
	if !.closed {
		.closeErr = 
	}
}

func ( *Listener) () {
	.gate.Lock()
}

func ( *Listener) () {
	.gate.Unlock(.acceptErr != nil || .queue.len() > 0)
}