// Copyright 2025 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice, this
//     list of conditions and the following disclaimer.
//
//  2. Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//  3. Neither the name of the copyright holder nor the names of its
//     contributors may be used to endorse or promote products derived from
//     this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package node

import (
	"bytes"
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

func TestPortListener_Write(t *testing.T) {
	tests := []struct {
		name          string
		inputs        [][]byte
		expectedPort  int
		expectPort    bool
		expectedError string
		expectedOut   string
	}{
		{
			name: "Port in single write",
			inputs: [][]byte{
				[]byte("Listening on [[12345]]"),
			},
			expectedPort: 12345,
			expectPort:   true,
			expectedOut:  "",
		},
		{
			name: "Port split across writes",
			inputs: [][]byte{
				[]byte("Listening on [[12"),
				[]byte("345]]"),
			},
			expectedPort: 12345,
			expectPort:   true,
			expectedOut:  "",
		},
		{
			name: "Port with trailing data after port found",
			inputs: [][]byte{
				[]byte("Listening on [[12345]] Some other output"),
			},
			expectedPort: 12345,
			expectPort:   true,
			expectedOut:  " Some other output",
		},
		{
			name: "No port in input",
			inputs: [][]byte{
				[]byte("Server starting..."),
				[]byte("Still no port."),
			},
			expectPort:  false,
			expectedOut: "",
		},
		{
			name: "Partial port start, no end",
			inputs: [][]byte{
				[]byte("Listening on [[12345"),
			},
			expectPort:  false,
			expectedOut: "",
		},
		{
			name: "Invalid port number",
			inputs: [][]byte{
				[]byte("Listening on [[abc]]"),
			},
			expectPort:    false,
			expectedError: `strconv.Atoi: parsing "abc": invalid syntax`,
			expectedOut:   "",
		},
		{
			name: "Empty port",
			inputs: [][]byte{
				[]byte("Listening on [[]]"),
			},
			expectPort:    false,
			expectedError: `strconv.Atoi: parsing "": invalid syntax`,
			expectedOut:   "",
		},
		{
			name: "Port at beginning of input",
			inputs: [][]byte{
				[]byte("[[7777]] Server ready"),
			},
			expectedPort: 7777,
			expectPort:   true,
			expectedOut:  " Server ready",
		},
		{
			name: "Writes after port found",
			inputs: [][]byte{
				[]byte("Listening on [[12345]]"),
				[]byte("More data"),
				[]byte(" and even more"),
			},
			expectedPort: 12345,
			expectPort:   true,
			expectedOut:  "More data and even more",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var outBuf bytes.Buffer
			pl := newPortListener(&outBuf)

			// Channel to receive the port or signal closure from the goroutine
			portResultChan := make(chan struct {
				port int
				ok   bool
			}, 1) // Buffer 1 to allow goroutine to send and exit without blocking

			// Start a goroutine to read from pl.port.
			// This is necessary because pl.port is unbuffered, and pl.Write will block
			// until the port is read.
			go func() {
				pVal, pOk := <-pl.port
				portResultChan <- struct {
					port int
					ok   bool
				}{pVal, pOk}
			}()

			var writeErr error
			for _, input := range tt.inputs {
				// If pl.Write sends to pl.port, the goroutine above will receive it,
				// unblocking pl.Write.
				_, currentErr := pl.Write(input)
				if currentErr != nil {
					writeErr = currentErr // Capture the first error
					break
				}
			}

			if tt.expectedError != "" {
				require.Error(t, writeErr, "Expected an error from Write")
				require.Contains(t, writeErr.Error(), tt.expectedError, "Error message mismatch")

				// If Write errored (e.g. strconv), pl.port might not be written to or closed by portListener.
				// The reading goroutine would block. We check portResultChan with a timeout.
				select {
				case res := <-portResultChan:
					t.Errorf("Unexpected port result (%+v) when Write error was expected", res)
				case <-time.After(50 * time.Millisecond):
					// Expected: goroutine is likely blocked as port was not sent/channel not closed due to error.
				}
			} else {
				require.NoError(t, writeErr, "Expected no error from Write")
				if tt.expectPort {
					select {
					case res := <-portResultChan:
						require.True(t, res.ok, "Expected to read a port, but channel was closed prematurely by sender")
						require.Equal(t, tt.expectedPort, res.port, "Port number mismatch")
					case <-time.After(100 * time.Millisecond): // Timeout for expected port
						t.Fatal("Timeout waiting for expected port")
					}
				} else { // Not expecting port
					select {
					case res := <-portResultChan:
						if res.ok {
							t.Errorf("Did not expect port, but got %d", res.port)
						} else {
							// This means pl.port was closed by sender. portListener.Write only closes *after* sending a port.
							t.Error("Did not expect port, but port channel was closed by sender (implies port was sent and read)")
						}
					case <-time.After(50 * time.Millisecond):
						// Expected: goroutine is likely blocked on <-pl.port as no port was sent and channel not closed.
					}
				}
			}
			require.Equal(t, tt.expectedOut, strings.TrimRight(outBuf.String(), " \n"))

			if tt.expectPort && tt.expectedError == "" {
				testStr := "subsequent write"
				_, subsequentWriteErr := pl.Write([]byte(testStr))
				require.NoError(t, subsequentWriteErr, "Error during subsequent write")
				require.Contains(t, strings.TrimRight(outBuf.String(), " \n"), testStr)
			}
		})
	}
}
