// 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.

// This file implements the Zircon loglistener protocol.
package netboot

import (
	"bytes"
	"encoding/binary"
	"errors"
	"net"
	"os"
	"syscall"

	"golang.org/x/sys/unix"
)

// Magic constants used by the netboot protocol.
const (
	debugMagic = 0xAEAE1123 // see system/public/zircon/boot/netboot.h
)

// Port numbers used by the netboot protocol.
const (
	debugPort = 33337 // debugging log port
)

// logpacket is the network logging protocol packet.
type logpacket struct {
	Magic    uint32
	Seqno    uint32
	Nodename [64]byte
	Data     [1216]byte
}

// LogListener is Zircon's debug log listener.
type LogListener struct {
	seq      uint32
	conn     net.PacketConn
	nodename string
}

// NewLogListener creates and connects a new instance of debug log listener.
func NewLogListener(nodename string) (*LogListener, error) {
	syscall.ForkLock.RLock()
	fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
	if err == nil {
		unix.CloseOnExec(fd)
	}
	syscall.ForkLock.RUnlock()
	if err != nil {
		return nil, err
	}

	// SO_REUSEADDR and SO_REUSEPORT allows binding to the same port multiple
	// times which is necessary in the case when there are multiple instances.
	if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	// Bind the socket to the defaut debug log listener port.
	if err := syscall.Bind(fd, &syscall.SockaddrInet6{Port: debugPort}); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	f := os.NewFile(uintptr(fd), "")
	conn, err := net.FilePacketConn(f)
	f.Close()
	if err != nil {
		return nil, err
	}

	return &LogListener{
		conn:     conn,
		nodename: nodename,
	}, nil
}

// Listen receive a single debug log packet.
func (l *LogListener) Listen() (string, error) {
	b := make([]byte, 4096)

	// Wait for logpacket.
	_, addr, err := l.conn.ReadFrom(b)
	if err != nil {
		return "", err
	}

	var pkt logpacket
	if err := binary.Read(bytes.NewReader(b), binary.LittleEndian, &pkt); err != nil {
		return "", err
	}
	if pkt.Magic != debugMagic {
		// Not a valid debug packet.
		return "", errors.New("invalid magic")
	}
	name, err := netbootString(pkt.Nodename[:])
	if err != nil {
		return "", err
	}
	if name != l.nodename {
		// Not a packet from our node.
		return "", errors.New("invalid nodename")
	}

	var data string
	if pkt.Seqno != l.seq {
		data, err = netbootString(pkt.Data[:])
		if err != nil {
			return data, err
		}
		l.seq = pkt.Seqno
	}

	// Acknowledge the packet.
	if _, err = l.conn.WriteTo(b[:8], addr); err != nil {
		return "", err
	}

	return data, nil
}

// Close shuts down the log listener underlying connection.
func (l *LogListener) Close() error {
	return l.conn.Close()
}
