// Copyright 2024 GoPacket Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.

package layers

import (
	"net"
	"reflect"
	"testing"

	"github.com/gopacket/gopacket"
)

// Frame 6: 279 bytes on wire (2232 bits), 279 bytes captured (2232 bits)
// Radiotap Header v0, Length 56
// 802.11 radio information
// IEEE 802.11 Data, Flags: ........C
// Logical-Link Control
//    DSAP: SNAP (0xaa)
//    SSAP: SNAP (0xaa)
//    Control field: U, func=UI (0x03)
//    Organization Code: 00:00:00 (Officially Xerox, but
//    Type: Unknown (0x0712)
// Meraki Discovery Protocol
//    Preamble Data: 0e0800002b58000400180004009f000009bef0040004cc1909bef004
//    Device Info
//        Type: Device Info (2)
//        Length: 13
//        Device Info: MR36-1 Eville
//    Network Info
//        Type: Network Info (3)
//        Length: 24
//        Network Info: Emeryville HQ - wireless
//    Longitude
//        Type: Longitude (4)
//        Length: 8
//        Longitude: 37.84773
//    Latitude
//        Type: Latitude (5)
//        Length: 10
//        Latitude: -122.29011
//    Type 6 UID
//        Type: Type 6 UID (6)
//        Length: 32
//        Type 6 UID: a1297f347ad7bcdfca5287fdba3d14d5
//    Type 7 UID
//        Type: Type 7 UID (7)
//        Length: 32
//        Type 7 UID: d484773ba890356f86e7afbdec76a646
//    Unknown type
//        Type: Unknown (11)
//        Length: 11
//    Unknown Data: 31302e3132382e312e3236
//    Unknown type
//        Type: Unknown (13)
//        Length: 5
//    Unknown Data: 66616c7365
//    Unknown type
//        Type: Unknown (12)
//        Length: 4
//    Unknown Data: 053b9f00
//    End
//        Type: End (255)
//        Length: 0

var testMDPFrame = []byte{
	0x00, 0x00, 0x38, 0x00, 0x2f, 0x40, 0x40, 0xa0, 0x20, 0x08, 0x00, 0xa0, 0x20, 0x08, 0x00, 0x00,
	0x61, 0x2b, 0x54, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x9e, 0x09, 0xa0, 0x00, 0xd1, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x2a, 0x54, 0x02, 0x00, 0x00, 0x00, 0x00,
	0x16, 0x00, 0x11, 0x03, 0xa8, 0x00, 0xd1, 0x01, 0x08, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xa6, 0x18, 0x88, 0xbe, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xbb,
	0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x07, 0x12, 0x0e, 0x08, 0x00, 0x00, 0x2b, 0x58, 0x00, 0x04,
	0x00, 0x18, 0x00, 0x04, 0x00, 0x9f, 0x00, 0x00, 0x09, 0xbe, 0xf0, 0x04, 0x00, 0x04, 0xcc, 0x19,
	0x09, 0xbe, 0xf0, 0x04, 0x02, 0x0d, 0x4d, 0x52, 0x33, 0x36, 0x2d, 0x31, 0x20, 0x45, 0x76, 0x69,
	0x6c, 0x6c, 0x65, 0x03, 0x18, 0x45, 0x6d, 0x65, 0x72, 0x79, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x20,
	0x48, 0x51, 0x20, 0x2d, 0x20, 0x77, 0x69, 0x72, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x04, 0x08, 0x33,
	0x37, 0x2e, 0x38, 0x34, 0x37, 0x37, 0x33, 0x05, 0x0a, 0x2d, 0x31, 0x32, 0x32, 0x2e, 0x32, 0x39,
	0x30, 0x31, 0x31, 0x06, 0x20, 0x61, 0x31, 0x32, 0x39, 0x37, 0x66, 0x33, 0x34, 0x37, 0x61, 0x64,
	0x37, 0x62, 0x63, 0x64, 0x66, 0x63, 0x61, 0x35, 0x32, 0x38, 0x37, 0x66, 0x64, 0x62, 0x61, 0x33,
	0x64, 0x31, 0x34, 0x64, 0x35, 0x07, 0x20, 0x64, 0x34, 0x38, 0x34, 0x37, 0x37, 0x33, 0x62, 0x61,
	0x38, 0x39, 0x30, 0x33, 0x35, 0x36, 0x66, 0x38, 0x36, 0x65, 0x37, 0x61, 0x66, 0x62, 0x64, 0x65,
	0x63, 0x37, 0x36, 0x61, 0x36, 0x34, 0x36, 0x0b, 0x0b, 0x31, 0x30, 0x2e, 0x31, 0x32, 0x38, 0x2e,
	0x31, 0x2e, 0x32, 0x36, 0x0d, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0c, 0x04, 0x05, 0x3b, 0x9f,
	0x00, 0xff, 0x00, 0x56, 0xe0, 0xf1, 0xf5,
}

func TestPacketMDP(t *testing.T) {
	p := gopacket.NewPacket(testMDPFrame, LinkTypeIEEE80211Radio, gopacket.Default)
	if p.ErrorLayer() != nil {
		t.Error("Failed to decode packet:", p.ErrorLayer().Error())
	}
	checkLayers(p, []gopacket.LayerType{
		LayerTypeRadioTap, LayerTypeDot11, LayerTypeDot11Data, LayerTypeLLC, LayerTypeSNAP, LayerTypeMDP,
	}, t)

	if got, ok := p.Layer(LayerTypeMDP).(*MDP); ok {
		want := &MDP{
			BaseLayer: BaseLayer{
				Contents: testMDPFrame[88 : len(testMDPFrame)-4],
				Payload:  nil,
			},
			Type:         EthernetTypeMerakiDiscoveryProtocol,
			Length:       len(testMDPFrame) - 92,
			PreambleData: testMDPFrame[88 : 88+28],
			DeviceInfo:   "MR36-1 Eville",
			NetworkInfo:  "Emeryville HQ - wireless",
			Longitude:    37.84773,
			Latitude:     -122.29011,
			Type6UUID:    "a1297f347ad7bcdfca5287fdba3d14d5",
			Type7UUID:    "d484773ba890356f86e7afbdec76a646",
			IPAddress:    net.ParseIP("10.128.1.26"),
			Type13Bool:   false,
		}

		if !reflect.DeepEqual(got, want) {
			t.Errorf("Dot11 packet processing failed:\ngot  :\n%#v\n\nwant :\n%#v\n\n", got, want)
		}
	}
}
