/*
 *
 * Copyright 2018 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

// Package testutils contains testing helpers.
package testutils

import (
	"errors"
	"net"
	"time"
)

var errClosed = errors.New("closed")

type pipeAddr struct{}

func (p pipeAddr) Network() string { return "pipe" }
func (p pipeAddr) String() string  { return "pipe" }

// PipeListener is a listener with an unbuffered pipe. Each write will complete only once the other side reads. It
// should only be created using NewPipeListener.
type PipeListener struct {
	c    chan chan<- net.Conn
	done chan struct{}
}

// NewPipeListener creates a new pipe listener.
func NewPipeListener() *PipeListener {
	return &PipeListener{
		c:    make(chan chan<- net.Conn),
		done: make(chan struct{}),
	}
}

// Accept accepts a connection.
func (p *PipeListener) Accept() (net.Conn, error) {
	var connChan chan<- net.Conn
	select {
	case <-p.done:
		return nil, errClosed
	case connChan = <-p.c:
		select {
		case <-p.done:
			close(connChan)
			return nil, errClosed
		default:
		}
	}
	c1, c2 := net.Pipe()
	connChan <- c1
	close(connChan)
	return c2, nil
}

// Close closes the listener.
func (p *PipeListener) Close() error {
	close(p.done)
	return nil
}

// Addr returns a pipe addr.
func (p *PipeListener) Addr() net.Addr {
	return pipeAddr{}
}

// Dialer dials a connection.
func (p *PipeListener) Dialer() func(string, time.Duration) (net.Conn, error) {
	return func(string, time.Duration) (net.Conn, error) {
		connChan := make(chan net.Conn)
		select {
		case p.c <- connChan:
		case <-p.done:
			return nil, errClosed
		}
		conn, ok := <-connChan
		if !ok {
			return nil, errClosed
		}
		return conn, nil
	}
}
