// 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"
)

const (
	defaultBaudRate = 115200

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

	// Timeout for reads and writes from a SerialSocket.
	socketIOTimeout = 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},
}

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
}

func (s *SerialSocket) Read(p []byte) (int, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.Conn.SetReadDeadline(time.Now().Add(socketIOTimeout))
	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(socketIOTimeout))
	return s.Conn.Write(p)
}

// 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) {
	if socketPath == "" {
		return nil, fmt.Errorf("serialSocketPath not set")
	}
	conn, err := net.Dial("unix", socketPath)
	if err != nil {
		return nil, fmt.Errorf("failed to open serial socket connection: %v", err)
	}
	socket := &SerialSocket{Conn: conn}
	// 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()
	m := iomisc.NewMatchingReader(socket, [][]byte{[]byte(consoleCursor)})
	if _, err = iomisc.ReadUntilMatch(ctx, m); err != nil {
		return nil, fmt.Errorf("failed to find cursor: %v", 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)
}
