package protocol

import (
	"encoding/base64"
	"reflect"
	"testing"
)

func TestGenerateKeyNonce(t *testing.T) {
	// Vectors from ts3j EncryptionTest.java
	ivStructBase64 := "/rn6nR71hV8eFl+15WO68fRU8pOCBw3t0FmcG5c7WNxIkeZ1NtaWTVMBde0cdU5tTKwOl8sE6gpHjnCEF4hhDw=="
	expectedKeyBase64 := "BF+lO776+e45u+qYAOHihg=="
	expectedNonceBase64 := "1IVcTMuizpDHjQgn2yGCgg=="

	ivStruct, _ := base64.StdEncoding.DecodeString(ivStructBase64)
	expectedKey, _ := base64.StdEncoding.DecodeString(expectedKeyBase64)
	expectedNonce, _ := base64.StdEncoding.DecodeString(expectedNonceBase64)

	// CryptoState setup
	crypto := &CryptoState{
		SharedIV:     ivStruct,
		GenerationID: 0,
	}

	// Packet Header setup
	// Packet ID = 1
	// Type = COMMAND (2)
	// Flags = NEW_PROTOCOL (0x20)
	// Type in Header struct contains (Type | Flags)
	// byte(2) | byte(0x20) = 0x22

	header := &PacketHeader{
		PacketID: 1,
		Type:     uint8(PacketTypeCommand) | PacketFlagNewProtocol,
	}
	// Note: PacketTypeCommand is 0x02. PacketFlagNewProtocol is 0x20.
	// Header.Type is uint8.

	// Generate (Client -> Server = true)
	// ts3j test uses ProtocolRole.CLIENT which maps to 0x31 for temporaryByteBuffer?
	// PacketTransformation.java: (header.getRole() == ProtocolRole.SERVER ? 0x30 : 0x31)
	// If EncryptionTest creates Packet(ProtocolRole.CLIENT), then header role is CLIENT.
	// So byte is 0x31.
	// In my crypto.go, GenerateKeyNonce(..., isClientToServer bool).
	// If client sends, isClientToServer should be true. (maps to 0x31).

	key, nonce := crypto.GenerateKeyNonce(header, true)

	if !reflect.DeepEqual(key, expectedKey) {
		t.Errorf("Key mismatch.\nGot:  %x\nWant: %x", key, expectedKey)
	}

	if !reflect.DeepEqual(nonce, expectedNonce) {
		t.Errorf("Nonce mismatch.\nGot:  %x\nWant: %x", nonce, expectedNonce)
	}
}
