
// mySeedPhrases provides functions to manage a user's seed phrases

package mySeedPhrases

import "seekia/internal/encoding"
import "seekia/internal/identity"
import "seekia/internal/myDatastores/myMap"
import "seekia/internal/seedPhrase"

import "errors"

// Map Structure: Identity Type -> My seed phrase
var mySeedPhrasesMapDatastore *myMap.MyMap

// This function must be called whenever an app user signs in
func InitializeMySeedPhrasesDatastore()error{

	newMySeedPhrasesMapDatastore, err := myMap.CreateNewMap("MySeedPhrases")
	if (err != nil) { return err }

	mySeedPhrasesMapDatastore = newMySeedPhrasesMapDatastore

	return nil
}

//Outputs:
//	-bool: My seed phrase exists
//	-[32]byte: My seed phrase hash
//	-error
func GetMySeedPhraseHash(myIdentityType string)(bool, [32]byte, error){

	exists, mySeedPhrase, err := GetMySeedPhrase(myIdentityType)
	if (err != nil) { return false, [32]byte{}, err }
	if (exists == false) {
		return false, [32]byte{}, nil
	}

	mySeedPhraseHash, err := seedPhrase.ConvertSeedPhraseToSeedPhraseHash(mySeedPhrase)
	if (err != nil) { return false, [32]byte{}, err }

	return true, mySeedPhraseHash, nil
}



// This function will verify that the seed phrase hash belongs to the identity hash
// This is necessary because the seed phrase can be changed by the user
// Use this function when you need to guarantee that the seed phrase belongs to the requested identityHash
//Outputs:
//	-bool: Found identity hash seed phrase hash
//	-[32]byte: Seed phrase hash
//	-error
func GetMySeedPhraseHashFromIdentityHash(inputIdentityHash [16]byte)(bool, [32]byte, error){

	identityType, err := identity.GetIdentityTypeFromIdentityHash(inputIdentityHash)
	if (err != nil) {
		inputIdentityHashHex := encoding.EncodeBytesToHexString(inputIdentityHash[:])
		return false, [32]byte{}, errors.New("GetMySeedPhraseHashFromIdentityHash called with invalid identityHash: " + inputIdentityHashHex)
	}

	exists, mySeedPhraseHash, err := GetMySeedPhraseHash(identityType)
	if (err != nil) { return false, [32]byte{}, err }
	if (exists == false) {
		return false, [32]byte{}, nil
	}

	myIdentityHash, err := identity.GetIdentityHashFromSeedPhraseHash(mySeedPhraseHash, identityType)
	if (err != nil) { return false, [32]byte{}, err }
	if (myIdentityHash != inputIdentityHash) {
		// Identity must have been replaced after identity hash was initially retrieved
		return false, [32]byte{}, nil
	}

	return true, mySeedPhraseHash, nil
}



//Outputs:
//	-bool: My seed phrase exists
//	-string: My seed phrase
//	-error
func GetMySeedPhrase(identityType string)(bool, string, error){

	if (identityType != "Mate" && identityType != "Host" && identityType != "Moderator"){
		return false, "", errors.New("GetMySeedPhrase called with invalid identity type: " + identityType)
	}

	exists, mySeedPhrase, err := mySeedPhrasesMapDatastore.GetMapEntry(identityType)
	if (err != nil) { return false, "", err }
	if (exists == false) {
		return false, "", nil
	}

	isValid := seedPhrase.VerifySeedPhrase(mySeedPhrase)
	if (isValid == false) {
		return false, "", errors.New("My existing seed phrase is invalid: " + mySeedPhrase)
	}

	return true, mySeedPhrase, nil
}

func SetMySeedPhrase(identityType string, newSeedPhrase string)error{

	if (identityType != "Mate" && identityType != "Host" && identityType != "Moderator"){
		return errors.New("SetMySeedPhrase called with invalid identity type: " + identityType)		
	}

	isValid := seedPhrase.VerifySeedPhrase(newSeedPhrase)
	if (isValid == false) {
		return errors.New("SetMySeedPhrase called with invalid seed phrase: " + newSeedPhrase)
	}

	err := mySeedPhrasesMapDatastore.SetMapEntry(identityType, newSeedPhrase)
	if (err != nil) { return err }

	return nil
}


func DeleteMySeedPhrase(identityType string)error{

	if (identityType != "Mate" && identityType != "Host" && identityType != "Moderator"){
		return errors.New("DeleteMySeedPhrase called with invalid identity type: " + identityType)
	}

	err := mySeedPhrasesMapDatastore.DeleteMapEntry(identityType)
	if (err != nil){ return err }

	return nil
}


