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

package ipv4_test

import (
	"net"
	"runtime"
	"testing"

	"golang.org/x/net/ipv4"
	"golang.org/x/net/nettest"
)

var packetConnMulticastSocketOptionTests = []struct {
	net, proto, addr string
	grp, src         net.Addr
}{
	{"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727
	{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil},  // see RFC 4727

	{"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
	{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}},  // see RFC 5771
}

func TestPacketConnMulticastSocketOptions(t *testing.T) {
	switch runtime.GOOS {
	case "fuchsia", "hurd", "js", "nacl", "plan9", "zos":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
	if err != nil {
		t.Skipf("not available on %s", runtime.GOOS)
	}

	ok := nettest.SupportsRawSocket()
	for _, tt := range packetConnMulticastSocketOptionTests {
		if tt.net == "ip4" && !ok {
			t.Logf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
			continue
		}
		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()
		p := ipv4.NewPacketConn(c)
		defer p.Close()

		if tt.src == nil {
			testMulticastSocketOptions(t, p, ifi, tt.grp)
		} else {
			testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
		}
	}
}

var rawConnMulticastSocketOptionTests = []struct {
	grp, src net.Addr
}{
	{&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727

	{&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}

func TestRawConnMulticastSocketOptions(t *testing.T) {
	switch runtime.GOOS {
	case "fuchsia", "hurd", "js", "nacl", "plan9", "zos":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if !nettest.SupportsRawSocket() {
		t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
	}
	ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
	if err != nil {
		t.Skipf("not available on %s", runtime.GOOS)
	}

	for _, tt := range rawConnMulticastSocketOptionTests {
		c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()
		r, err := ipv4.NewRawConn(c)
		if err != nil {
			t.Fatal(err)
		}
		defer r.Close()

		if tt.src == nil {
			testMulticastSocketOptions(t, r, ifi, tt.grp)
		} else {
			testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src)
		}
	}
}

type testIPv4MulticastConn interface {
	MulticastTTL() (int, error)
	SetMulticastTTL(ttl int) error
	MulticastLoopback() (bool, error)
	SetMulticastLoopback(bool) error
	JoinGroup(*net.Interface, net.Addr) error
	LeaveGroup(*net.Interface, net.Addr) error
	JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
	LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
	ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
	IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
}

func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) {
	t.Helper()

	const ttl = 255
	if err := c.SetMulticastTTL(ttl); err != nil {
		t.Error(err)
		return
	}
	if v, err := c.MulticastTTL(); err != nil {
		t.Error(err)
		return
	} else if v != ttl {
		t.Errorf("got %v; want %v", v, ttl)
		return
	}

	for _, toggle := range []bool{true, false} {
		if err := c.SetMulticastLoopback(toggle); err != nil {
			t.Error(err)
			return
		}
		if v, err := c.MulticastLoopback(); err != nil {
			t.Error(err)
			return
		} else if v != toggle {
			t.Errorf("got %v; want %v", v, toggle)
			return
		}
	}

	if err := c.JoinGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
}

func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) {
	t.Helper()

	// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
	if err := c.JoinGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
	if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
		switch runtime.GOOS {
		case "freebsd", "linux":
		default: // platforms that don't support IGMPv2/3 fail here
			t.Logf("not supported on %s", runtime.GOOS)
			return
		}
		t.Error(err)
		return
	}
	if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}

	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}

	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
}
