
// myDevice provides functions to generate device identifiers
// These are used to let other users know if the user has changed devices
// Upon learning this, users will wait to download new chat keys and discard any secret inboxes they had stored from the user

package myDevice

import "seekia/internal/cryptography/blake3"
import "seekia/internal/encoding"
import "seekia/internal/helpers"
import "seekia/internal/mySeedPhrases"
import "seekia/internal/mySettings"

import "errors"
import "slices"
import "sync"


var initializingDeviceSeedMutex sync.Mutex

//Outputs:
//	-bool: My identity found
//	-[11]byte: Device identifier
//	-error
func GetMyDeviceIdentifier(myIdentityHash [16]byte, networkType byte)(bool, [11]byte, error){

	isValid := helpers.VerifyNetworkType(networkType)
	if (isValid == false){
		networkTypeString := helpers.ConvertByteToString(networkType)
		return false, [11]byte{}, errors.New("GetMyDeviceIdentifier called with invalid networkType: " + networkTypeString)
	}

	identityFound, mySeedPhraseHash, err := mySeedPhrases.GetMySeedPhraseHashFromIdentityHash(myIdentityHash)
	if (err != nil) { return false, [11]byte{}, err }
	if (identityFound == false){
		return false, [11]byte{}, nil
	}

	getMyDeviceSeed := func()(string, error){

		initializingDeviceSeedMutex.Lock()
		defer initializingDeviceSeedMutex.Unlock()

		exists, myDeviceSeed, err := mySettings.GetSetting("DeviceSeed")
		if (err != nil){ return "", err }
		if (exists == true){
			return myDeviceSeed, nil
		}

		newDeviceSeed, err := helpers.GetNewRandomHexString(64)
		if (err != nil) { return "", err }

		err = mySettings.SetSetting("DeviceSeed", newDeviceSeed)
		if (err != nil) { return "", err }

		return newDeviceSeed, nil
	}

	myDeviceSeed, err := getMyDeviceSeed()
	if (err != nil) { return false, [11]byte{}, err }

	deviceSeedBytes, err := encoding.DecodeHexStringToBytes(myDeviceSeed)
	if (err != nil) {
		return false, [11]byte{}, errors.New("My device seed is invalid: Not Hex: " + myDeviceSeed)
	}

	if (len(deviceSeedBytes) != 64){
		return false, [11]byte{}, errors.New("My device seed is invalid: Invalid length: " + myDeviceSeed)
	}

	hashSalt, err := encoding.DecodeBase32StringToBytes("mydevice")
	if (err != nil) { return false, [11]byte{}, err }

	hashInput := slices.Concat(mySeedPhraseHash[:], hashSalt)
	hashInput = append(hashInput, networkType)
	hashInput = append(hashInput, deviceSeedBytes...)

	deviceIdentifier, err := blake3.GetBlake3HashAsBytes(11, hashInput)
	if (err != nil) { return false, [11]byte{}, err }

	deviceIdentifierArray := [11]byte(deviceIdentifier)

	return true, deviceIdentifierArray, nil
}





