// Copyright 2021 The Fuchsia 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 serial

import (
	"context"
	"fmt"
	"io"
	"math/rand"
	"net"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/sync/errgroup"

	"go.fuchsia.dev/fuchsia/tools/lib/iomisc"
)

type fakeSerialServer struct {
	received       []byte
	shutdownString string
	socketPath     string
	listeningChan  chan bool
}

func (s *fakeSerialServer) Serve() error {
	listener, err := net.Listen("unix", s.socketPath)
	if err != nil {
		s.listeningChan <- false
		return fmt.Errorf("Listen(%s) failed: %v", s.socketPath, err)
	}
	defer listener.Close()
	s.listeningChan <- true
	conn, err := listener.Accept()
	if err != nil {
		return fmt.Errorf("Accept() failed: %v", err)
	}
	defer conn.Close()
	// Signal we're ready to accept input.
	if _, err := conn.Write([]byte(consoleCursor)); err != nil {
		return fmt.Errorf("conn.Write() failed: %v", err)
	}
	reader := iomisc.NewMatchingReader(conn, []byte(s.shutdownString))
	for {
		buf := make([]byte, 1024)
		bytesRead, err := reader.Read(buf)
		s.received = append(s.received, buf[:bytesRead]...)
		if err != nil {
			if err == io.EOF {
				return nil
			}
			return fmt.Errorf("conn.Read() failed: %v", err)
		}
	}
}

func TestRunCommands(t *testing.T) {
	socketPath := fmt.Sprintf("%d.sock", rand.Uint32())
	defer os.Remove(socketPath)
	server := fakeSerialServer{
		shutdownString: "power shutdown",
		socketPath:     socketPath,
		listeningChan:  make(chan bool),
	}
	eg := errgroup.Group{}
	eg.Go(server.Serve)

	if !<-server.listeningChan {
		t.Fatalf("fakeSerialServer.Serve() returned: %v", eg.Wait())
	}

	clientSocket, err := NewSocket(context.Background(), socketPath)
	if err != nil {
		t.Fatalf("NewSocket() failed: %v", err)
	}

	// Test that SetIOTimeout causes the socket to return from Read() even
	// if there is nothing to read.
	clientSocket.SetIOTimeout(time.Nanosecond)
	buf := make([]byte, 10)
	_, err = clientSocket.Read(buf)
	if err == nil {
		t.Errorf("expected Read() to get an error, got nil")
	}
	clientSocket.SetIOTimeout(defaultSocketIOTimeout)

	diagnosticCmds = []Command{
		{
			Cmd: []string{"foo"},
			// Ensure we don't waste time sleeping in this test.
			SleepDuration: time.Microsecond,
		},
		{
			Cmd: []string{"bar"},
			// Ensure we don't waste time sleeping in this test.
			SleepDuration: time.Microsecond,
		},
		{
			// This is a hack to ensure the shutdown command gets sent to the serial server.
			// Rather than introduce a new synchronization mechanism, just use the code under test's
			// existing mechanism for sending commands.
			Cmd: []string{server.shutdownString},
			// Ensure we don't waste time sleeping in this test.
			SleepDuration: time.Microsecond,
		},
	}
	// RunDiagnostics calls RunCommands so this covers both functions for testability.
	err = RunDiagnostics(context.Background(), clientSocket)
	if err != nil {
		t.Errorf("RunDiagnostics failed: %v", err)
	}
	if err = eg.Wait(); err != nil {
		t.Errorf("server returned: %v", err)
	}
	if err = clientSocket.Close(); err != nil {
		t.Errorf("clientSocket.Close() returned: %v", err)
	}
	// Verify that each command was seen in the received data, and in the
	// proper order. The first command run was an empty command in NewSocket().
	var expectedCommands strings.Builder
	expectedCommands.WriteString(asSerialCmd([]string{}))
	for _, cmd := range diagnosticCmds {
		expectedCommands.WriteString(asSerialCmd(cmd.Cmd))
	}
	if diff := cmp.Diff(expectedCommands.String(), string(server.received)); diff != "" {
		t.Errorf("Unexpected server.received (-want +got):\n%s", diff)
	}
}
