// Copyright 2018 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 provides support for serial connections.
package serial

import (
	"context"
	"fmt"
	"io"
	"net"
	"strings"
	"sync"
	"time"

	"go.fuchsia.dev/fuchsia/tools/lib/iomisc"
	"go.fuchsia.dev/fuchsia/tools/lib/logger"
	"go.fuchsia.dev/fuchsia/tools/lib/serial/constants"
)

const (
	defaultBaudRate = 115200

	// Printed to the serial console when ready to accept user input.
	consoleCursor = "$ "

	// Timeout for reads and writes from a SerialSocket.
	defaultSocketIOTimeout = 2 * time.Minute
)

var diagnosticCmds = []Command{
	{[]string{"k", "threadload"}, 200 * time.Millisecond}, // Turn on threadload
	{[]string{"k", "threadq"}, 5 * time.Second},           // Turn on threadq and wait 5 sec
	{[]string{"k", "cpu", "sev"}, 5 * time.Second},        // Send a SEV and wait 5 sec
	{[]string{"k", "threadload"}, 200 * time.Millisecond}, // Turn off threadload
	{[]string{"k", "threadq"}, 0},                         // Turn off threadq
	// Invoke the threads command twice to identify hanging processes.
	{[]string{"threads", "--all-processes"}, 5 * time.Minute},
	{[]string{"threads", "--all-processes"}, 5 * time.Minute},
	// Print netstack goroutines while only using shell-builtin commands to
	// avoid hitting the package resolver.
	{[]string{`(export PATH=; export P="$(echo hub-v2/children/core/children/network/children/netstack/exec/out/debug/goroutines)" && test -e "$P" && while IFS='' read line; do echo "$line"; done < "$P";) &`}, 1 * time.Minute},
}

type SerialSocket struct {
	net.Conn

	// It's only safe for one goroutine at a time to read or write from the
	// socket at a time.
	mu        sync.Mutex
	ioTimeout time.Duration
}

func (s *SerialSocket) Read(p []byte) (int, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.Conn.SetReadDeadline(time.Now().Add(s.ioTimeout))
	return s.Conn.Read(p)
}

func (s *SerialSocket) Write(p []byte) (int, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.Conn.SetWriteDeadline(time.Now().Add(s.ioTimeout))
	return s.Conn.Write(p)
}

// SetIOTimeout sets the timeout for a single Read() or Write().
func (s *SerialSocket) SetIOTimeout(timeout time.Duration) {
	s.ioTimeout = timeout
}

// Open opens a new serial port using defaults.
func Open(name string) (io.ReadWriteCloser, error) {
	return OpenWithOptions(name, defaultBaudRate)
}

// OpenWithOptions opens a new serial port with the given name and baud rate.
func OpenWithOptions(name string, baudRate int) (io.ReadWriteCloser, error) {
	return open(name, baudRate)
}

// Command contains the command to run over serial and the expected duration
// to wait for the command to complete.
type Command struct {
	Cmd           []string
	SleepDuration time.Duration
}

func asSerialCmd(cmd []string) string {
	// The UART kernel driver expects a command to be followed by \r\n.
	// Send a leading \r\n for all commands as there may be characters in the buffer already
	// that we need to clear first.
	return fmt.Sprintf("\r\n%s\r\n", strings.Join(cmd, " "))
}

// NewSocket opens a connection on the provided `socketPath`.
func NewSocket(ctx context.Context, socketPath string) (*SerialSocket, error) {
	return NewSocketWithIOTimeout(ctx, socketPath, defaultSocketIOTimeout, true)
}

// NewSocketWithIOTimeout opens a connection on the provided `socketPath` with
// the provided socket IO timeout for reads and writes.
func NewSocketWithIOTimeout(ctx context.Context, socketPath string, ioTimeout time.Duration, waitUntilReady bool) (*SerialSocket, error) {
	if socketPath == "" {
		return nil, fmt.Errorf("serialSocketPath not set")
	}
	conn, err := net.Dial("unix", socketPath)
	if err != nil {
		return nil, fmt.Errorf("%s: %w", constants.FailedToOpenSerialSocketMsg, err)
	}
	if ioTimeout <= 0 {
		ioTimeout = defaultSocketIOTimeout
	}
	socket := &SerialSocket{Conn: conn, ioTimeout: ioTimeout}
	if waitUntilReady {
		// Trigger a new cursor print by sending a newline. This may do nothing if the
		// system was not ready to process input, but in that case it will print a
		// new cursor anyways when it is ready to receive input.
		io.WriteString(socket, asSerialCmd([]string{}))
		// Look for the cursor, which should indicate that the console is ready for input.
		ctx, cancel := context.WithTimeout(ctx, 45*time.Second)
		defer cancel()
		if _, err = iomisc.ReadUntilMatchString(ctx, socket, consoleCursor); err != nil {
			socket.Close()
			return nil, fmt.Errorf("%s: %w", constants.FailedToFindCursorMsg, err)
		}
	}
	return socket, nil
}

// RunCommands writes the provided commands to the serial socket.
func RunCommands(ctx context.Context, socket io.ReadWriteCloser, cmds []Command) error {
	for _, cmd := range cmds {
		logger.Debugf(ctx, "running over serial: %v", cmd.Cmd)

		if _, err := io.WriteString(socket, asSerialCmd(cmd.Cmd)); err != nil {
			return fmt.Errorf("failed to write to serial socket: %v", err)
		}

		if cmd.SleepDuration > 0 {
			logger.Debugf(ctx, "sleeping for %v", cmd.SleepDuration)
			time.Sleep(cmd.SleepDuration)
		}
	}
	return nil
}

// RunDiagnostics runs a series of diagnostic commands over serial.
func RunDiagnostics(ctx context.Context, socket io.ReadWriteCloser) error {
	logger.Debugf(ctx, "attempting to run diagnostics over serial")
	return RunCommands(ctx, socket, diagnosticCmds)
}
