package ch3

import (
	"io"
	"net"
	"testing"
)

func TestDial(t *testing.T) {
	//create a listener on a random port to make out test connection to
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	t.Log("Test server listening on:", listener.Addr().String())
	if err != nil {
		t.Fatal(err)
	}

	// channel that receives struct objects
	done := make(chan struct{})

	// Goroutine (aka handler) for listening for connections
	go func() {
		defer func() { done <- struct{}{} }()

		for {
			conn, err := listener.Accept()
			if err != nil {
				t.Log(err)
				return
			}
			// goroutine for responding to connection requests
			go func(c net.Conn) {
				defer func() {
					c.Close()
					done <- struct{}{}
				}()

				// create a slice of size 1024 (1 kilobyte)
				buf := make([]byte, 1024)
				for {
					// reads up to 1024 bytes at a time from the socket
					n, err := c.Read(buf)
					if err != nil {
						// c.Read returns io.EOF when FIN packet (graceful termination) is received
						if err != io.EOF {
							t.Log("FIN packet received.")
							t.Error(err)
						}
						return
					}
					// logs the bytes it receives
					t.Logf("received: %q", buf[:n])
				}
			}(conn)

		}
	}()

	// Now we make our client
	conn, err := net.Dial("tcp", listener.Addr().String())
	if err != nil {
		t.Fatal(err)
	}

	conn.Close()
	<-done
	listener.Close()
	<-done
}
