// Copyright 2021 The Go 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 linux
// +build linux

package unix

import (
	"bytes"
	"net"
	"testing"
	"unsafe"
)

// An ifreqUnion is shorthand for a byte array matching the
// architecture-dependent size of an ifreq's union field.
type ifreqUnion = [len(ifreq{}.Ifru)]byte

func TestNewIfreq(t *testing.T) {
	// Interface name too long.
	if _, err := NewIfreq("abcdefghijklmnop"); err != EINVAL {
		t.Fatalf("expected error EINVAL, but got: %v", err)
	}
}

func TestIfreqSize(t *testing.T) {
	// Ensure ifreq (generated) and Ifreq/ifreqData (hand-written to create a
	// safe wrapper and store a pointer field) are identical in size.
	want := unsafe.Sizeof(ifreq{})
	if got := unsafe.Sizeof(Ifreq{}); want != got {
		t.Fatalf("unexpected Ifreq size: got: %d, want: %d", got, want)
	}

	if got := unsafe.Sizeof(ifreqData{}); want != got {
		t.Fatalf("unexpected IfreqData size: got: %d, want: %d", got, want)
	}
}

func TestIfreqName(t *testing.T) {
	// Valid ifreq, expect the hard-coded testIfreq name.
	ifr := testIfreq(t)
	if want, got := ifreqName, ifr.Name(); want != got {
		t.Fatalf("unexpected ifreq name: got: %q, want: %q", got, want)
	}
}

func TestIfreqWithData(t *testing.T) {
	ifr := testIfreq(t)

	// Store pointer data in the ifreq so we can retrieve it and cast back later
	// for comparison.
	want := [5]byte{'h', 'e', 'l', 'l', 'o'}
	ifrd := ifr.withData(unsafe.Pointer(&want[0]))

	// Ensure the memory of the original Ifreq was not modified by SetData.
	if ifr.raw.Ifru != (ifreqUnion{}) {
		t.Fatalf("ifreq was unexpectedly modified: % #x", ifr.raw.Ifru)
	}

	got := *(*[5]byte)(ifrd.data)
	if want != got {
		t.Fatalf("unexpected ifreq data bytes:\n got: % #x\nwant: % #x", got, want)
	}
}

func TestIfreqInet4Addr(t *testing.T) {
	ifr := testIfreq(t)
	in := net.IPv4(192, 0, 2, 1).To4()
	if err := ifr.SetInet4Addr(in); err != nil {
		t.Fatalf("failed to set ifreq IPv4 address: %v", err)
	}

	// Store fixed offset data (AF_INET, IPv4 address) within underlying
	// sockaddr bytes. Everything else should be zeroed.
	want := ifreqUnion{4: 192, 5: 0, 6: 2, 7: 1}
	if isBigEndian {
		want[0] = 0x00
		want[1] = 0x02
	} else {
		want[0] = 0x02
		want[1] = 0x00
	}

	if got := ifr.raw.Ifru; want != got {
		t.Fatalf("unexpected ifreq sockaddr bytes:\n got: % #x\nwant: % #x", got, want)
	}

	got, err := ifr.Inet4Addr()
	if err != nil {
		t.Fatalf("failed to get ifreq IPv4 address: %v", err)
	}
	if !bytes.Equal(in, got) {
		t.Fatalf("unexpected ifreq IPv4 address:\n got: % #x\nwant: % #x", got, in)
	}

	// Invalid input, wrong length.
	if err := ifr.SetInet4Addr([]byte{0xff}); err == nil {
		t.Fatal("expected an error setting invalid IPv4 address, but none occurred")
	}

	// Invalid output, AF_INET is only set by SetInet4Addr input.
	ifr.SetUint32(0xffffffff)
	if _, err := ifr.Inet4Addr(); err == nil {
		t.Fatal("expected an error getting invalid IPv4 address, but none occurred")
	}
}

func TestIfreqUint16(t *testing.T) {
	ifr := testIfreq(t)
	const in = 0x0102
	ifr.SetUint16(in)

	// The layout of the bytes depends on the machine's endianness.
	var want ifreqUnion
	if isBigEndian {
		want[0] = 0x01
		want[1] = 0x02
	} else {
		want[0] = 0x02
		want[1] = 0x01
	}

	if got := ifr.raw.Ifru; want != got {
		t.Fatalf("unexpected ifreq uint16 bytes:\n got: % #x\nwant: % #x", got, want)
	}

	if got := ifr.Uint16(); in != got {
		t.Fatalf("unexpected ifreq uint16: got: %d, want: %d", got, in)
	}
}

func TestIfreqUint32(t *testing.T) {
	ifr := testIfreq(t)
	const in = 0x01020304
	ifr.SetUint32(in)

	// The layout of the bytes depends on the machine's endianness.
	var want ifreqUnion
	if isBigEndian {
		want[0] = 0x01
		want[1] = 0x02
		want[2] = 0x03
		want[3] = 0x04
	} else {
		want[0] = 0x04
		want[1] = 0x03
		want[2] = 0x02
		want[3] = 0x01
	}

	if got := ifr.raw.Ifru; want != got {
		t.Fatalf("unexpected ifreq uint32 bytes:\n got: % #x\nwant: % #x", got, want)
	}

	if got := ifr.Uint32(); in != got {
		t.Fatalf("unexpected ifreq uint32: got: %d, want: %d", got, in)
	}
}

// ifreqName is a hard-coded name for testIfreq.
const ifreqName = "eth0"

// testIfreq returns an Ifreq with a populated interface name.
func testIfreq(t *testing.T) *Ifreq {
	t.Helper()

	ifr, err := NewIfreq(ifreqName)
	if err != nil {
		t.Fatalf("failed to create ifreq: %v", err)
	}

	return ifr
}
