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

//go:build !build_with_native_toolchain
// +build !build_with_native_toolchain

package testutil

import (
	"sync/atomic"
	"syscall/zx"
	"testing"
	"unsafe"

	ethernetext "go.fuchsia.dev/fuchsia/src/connectivity/network/netstack/fidlext/fuchsia/hardware/ethernet"

	"fidl/fuchsia/hardware/ethernet"
	"gen/netstack/link/eth"
)

// makeEntryFifo creates a pair of handles to a FIFO of "depth" FifoEntry
// elements for use in tests. The created handles are automatically closed on
// test cleanup.
func makeEntryFifo(t *testing.T, depth uint) (zx.Handle, zx.Handle) {
	t.Helper()
	var device, client zx.Handle
	if status := zx.Sys_fifo_create(depth, uint(unsafe.Sizeof(eth.FifoEntry{})), 0, &device, &client); status != zx.ErrOk {
		t.Fatalf("failed to create fake FIFO: %s", status)
	}
	t.Cleanup(func() {
		_ = device.Close()
		_ = client.Close()
	})
	return device, client
}

// Returns an ethernetext.Device struct that implements
// ethernet.Device and can be started and stopped.
//
// Reports the passed in ethernet.Info when Device#GetInfo is called.
func MakeEthernetDevice(t *testing.T, info ethernet.Info, depth uint32) (ethernetext.Device, ethernet.Fifos) {
	t.Helper()
	clientRxFifo, deviceRxFifo := makeEntryFifo(t, uint(depth))
	clientTxFifo, deviceTxFifo := makeEntryFifo(t, uint(depth))

	var started uint32
	return ethernetext.Device{
			TB:                t,
			GetInfoImpl:       func() (ethernet.Info, error) { return info, nil },
			SetClientNameImpl: func(string) (int32, error) { return 0, nil },
			GetStatusImpl: func() (ethernet.DeviceStatus, error) {
				var status ethernet.DeviceStatus
				if atomic.LoadUint32(&started) == 1 {
					status |= ethernet.DeviceStatusOnline
				}
				// Emulate the driver by clearing the signal. Note that without doing this the client would
				// hot-loop, continually observing the signal.
				err := deviceRxFifo.SignalPeer(zx.Signals(ethernet.SignalStatus), 0)
				return status, err
			},
			GetFifosImpl: func() (int32, *ethernet.Fifos, error) {
				return int32(zx.ErrOk), &ethernet.Fifos{
					Rx:      clientRxFifo,
					Tx:      clientTxFifo,
					RxDepth: depth,
					TxDepth: depth,
				}, nil
			},
			SetIoBufferImpl: func(h zx.VMO) (int32, error) {
				return int32(zx.ErrOk), h.Close()
			},
			StartImpl: func() (int32, error) {
				if atomic.CompareAndSwapUint32(&started, 0, 1) {
					switch err := deviceRxFifo.SignalPeer(0, zx.Signals(ethernet.SignalStatus)).(type) {
					case *zx.Error:
						return int32(err.Status), nil
					default:
						return int32(zx.ErrOk), err
					}
				}
				return int32(zx.ErrOk), nil
			},
			ConfigMulticastSetPromiscuousModeImpl: func(bool) (int32, error) {
				return int32(zx.ErrOk), nil
			},
			StopImpl: func() error {
				atomic.StoreUint32(&started, 0)
				return nil
			},
		}, ethernet.Fifos{
			Rx: deviceRxFifo,
			Tx: deviceTxFifo,
		}
}
