package identity_test

import "seekia/internal/identity"

import "seekia/internal/encoding"
import "seekia/internal/helpers"

import "testing"
import "bytes"

func TestRandomIdentity(t *testing.T){

	randomIdentityType, err := helpers.GetRandomItemFromList([]string{"Mate", "Host", "Moderator"})
	if (err != nil){
		t.Fatal("Failed to get random identityType: " + err.Error())
	}

	testIdentityHash, err := identity.GetNewRandomIdentityHash(true, randomIdentityType)
	if (err != nil){
		t.Fatal("GetNewRandomIdentityHash failed: " + err.Error())
	}

	identityType, err := identity.GetIdentityTypeFromIdentityHash(testIdentityHash)
	if (err != nil){
		t.Fatal("GetNewRandomIdentityHash returning invalid identity hash. Reason: " + err.Error())
	}
	
	if (identityType != randomIdentityType){
		t.Fatal("GetNewRandomIdentityHash returning identity hash of different identityType: " + identityType)
	}
}

func TestIdentityDerivation(t *testing.T){

	testSeedPhraseHashHex := "6c63469b0581a2633d37721d466b68ed9c3b3744352a5409792f84e24d19203d"

	testSeedPhraseHashBytes, err := encoding.DecodeHexStringToBytes(testSeedPhraseHashHex)
	if (err != nil){
		t.Fatal("testSeedPhraseHashHex is invalid: Not Hex: " + err.Error())
	}

	testSeedPhraseHashArray := [32]byte(testSeedPhraseHashBytes)

	expectedPublicIdentityKeyHex := "69b6735f22a3991215a139a666dcbb42e7a33fbab32109a185dd60ba2a5a150d"

	expectedPublicIdentityKeyBytes, err := encoding.DecodeHexStringToBytes(expectedPublicIdentityKeyHex)
	if (err != nil){
		t.Fatal("expectedPublicIdentityKeyHex is invalid: Not Hex: " + err.Error())
	}

	expectedPrivateIdentityKeyHex := "38a84046125d37b00343c281a91ea3e9b7edee50b82df2b5350b66f44985423369b6735f22a3991215a139a666dcbb42e7a33fbab32109a185dd60ba2a5a150d"

	expectedPrivateIdentityKeyBytes, err := encoding.DecodeHexStringToBytes(expectedPrivateIdentityKeyHex)
	if (err != nil){
		t.Fatal("expectedPrivateIdentityKeyHex is invalid: Not Hex: " + err.Error())
	}

	publicIdentityKey, privateIdentityKey, err := identity.GetPublicPrivateIdentityKeysFromSeedPhraseHash(testSeedPhraseHashArray)
	if (err != nil){
		t.Fatal("GetPublicPrivateIdentityKeysFromSeedPhraseHash failed: " + err.Error())
	}
	areEqual := bytes.Equal(publicIdentityKey[:], expectedPublicIdentityKeyBytes)
	if (areEqual == false){
		publicKeyHex := encoding.EncodeBytesToHexString(publicIdentityKey[:])
		t.Fatal("GetPublicPrivateIdentityKeysFromSeedPhraseHash returning invalid public identity key: " + publicKeyHex)
	}
	areEqual = bytes.Equal(privateIdentityKey[:], expectedPrivateIdentityKeyBytes)
	if (areEqual == false){
		privateKeyHex := encoding.EncodeBytesToHexString(privateIdentityKey[:])
		t.Fatal("GetPublicPrivateIdentityKeysFromSeedPhraseHash returning invalid private identity key: " + privateKeyHex)
	}

	identityHash, err := identity.ConvertIdentityKeyToIdentityHash(publicIdentityKey, "Mate")
	if (err != nil){
		t.Fatal("ConvertIdentityKeyToIdentityHash failed: " + err.Error())
	}

	expectedIdentityHash := "orvstztt4hp6rqjcpv2icocf5dm"

	expectedIdentityHashArray, identityType, err := identity.ReadIdentityHashString(expectedIdentityHash)
	if (err != nil){
		t.Fatal("Cannot read expectedIdentityHash: " + err.Error())
	}

	if (identityHash != expectedIdentityHashArray){

		identityHashString, _, err := identity.EncodeIdentityHashBytesToString(identityHash)
		if (err != nil){
			t.Fatal("ConvertIdentityKeyToIdentityHash returning invalid identity hash: " + err.Error())
		}

		t.Fatal("ReadIdentityHashString returning unexpected identity hash: " + identityHashString)
	}
	if (identityType != "Mate"){
		t.Fatal("ReadIdentityHashString returning unexpected identityType: " + identityType)
	}

	identityType, err = identity.GetIdentityTypeFromIdentityHash(identityHash)
	if (err != nil){
		t.Fatal("GetIdentityTypeFromIdentityHash fails to read valid mate identity hash.")
	}

	if (identityType != "Mate"){
		t.Fatal("GetIdentityTypeFromIdentityHash fails to read valid mate identity hash.")
	}

}


func TestIdentityEncoding(t *testing.T){

	testIdentityHash, err := identity.GetNewRandomIdentityHash(false, "")
	if (err != nil){
		t.Fatal("GetNewRandomIdentityHash failed: " + err.Error())
	}

	encodedIdentityHash, identityType, err := identity.EncodeIdentityHashBytesToString(testIdentityHash)
	if (err != nil){
		t.Fatal("EncodeIdentityHashBytesToString failed: " + err.Error())
	}

	identityHashBytes, identityType_Received, err := identity.ReadIdentityHashString(encodedIdentityHash)
	if (err != nil){
		t.Fatal("ReadIdentityHash failed: " + err.Error())
	}

	if (testIdentityHash != identityHashBytes){
		t.Fatal("Decoded identity hash does not match.")
	}
	if (identityType != identityType_Received){
		t.Fatal("Decoded identityType does not match.")
	}
}
