
// myConversationIndexes provides functions to keep track of the viewed message index of conversations
// Each index describes the page of messages that the user is viewing for each conversation

package myConversationIndexes

//TODO: Create function to prune indexes for conversations that no longer exist

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

import "errors"

var myConversationViewIndexesMapDatastore *myMap.MyMap

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

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

	myConversationViewIndexesMapDatastore = newMyConversationViewIndexesMapDatastore

	return nil
}


func SetConversationMessageViewIndex(myIdentityHash [16]byte, theirIdentityHash [16]byte, networkType byte, viewIndex int)error{

	myIdentityHashString, myIdentityType, err := identity.EncodeIdentityHashBytesToString(myIdentityHash)
	if (err != nil){
		myIdentityHashHex := encoding.EncodeBytesToHexString(myIdentityHash[:])
		return errors.New("SetConversationMessageViewIndex called with invalid myIdentityHash: " + myIdentityHashHex)
	}

	theirIdentityHashString, theirIdentityType, err := identity.EncodeIdentityHashBytesToString(theirIdentityHash)
	if (err != nil){
		theirIdentityHashHex := encoding.EncodeBytesToHexString(theirIdentityHash[:])
		return errors.New("SetConversationMessageViewIndex called with invalid theirIdentityHash: " + theirIdentityHashHex)
	}

	if (myIdentityType != theirIdentityType){
		return errors.New("SetConversationMessageViewIndex called with mismatched my/their identityTypes.")
	}
	if (myIdentityType == "Host"){
		return errors.New("SetConversationMessageViewIndex called with Host identityTypes.")
	}

	isValid := helpers.VerifyNetworkType(networkType)
	if (isValid == false){
		networkTypeString := helpers.ConvertByteToString(networkType)
		return errors.New("GetConversationMessageViewIndex called with invalid networkType: " + networkTypeString)
	}

	networkTypeString := helpers.ConvertByteToString(networkType)

	conversationKey := myIdentityHashString + "+" + theirIdentityHashString + "@" + networkTypeString

	mapEntryValue := helpers.ConvertIntToString(viewIndex)

	err = myConversationViewIndexesMapDatastore.SetMapEntry(conversationKey, mapEntryValue)
	if (err != nil) { return err }

	return nil
}

//Outputs:
//	-bool: Index exists
//	-int: Conversation index
//	-error
func GetConversationMessageViewIndex(myIdentityHash [16]byte, theirIdentityHash [16]byte, networkType byte)(bool, int, error){

	myIdentityHashString, myIdentityType, err := identity.EncodeIdentityHashBytesToString(myIdentityHash)
	if (err != nil){
		myIdentityHashHex := encoding.EncodeBytesToHexString(myIdentityHash[:])
		return false, 0, errors.New("GetConversationMessageViewIndex called with invalid myIdentityHash: " + myIdentityHashHex)
	}

	theirIdentityHashString, theirIdentityType, err := identity.EncodeIdentityHashBytesToString(theirIdentityHash)
	if (err != nil){
		theirIdentityHashHex := encoding.EncodeBytesToHexString(theirIdentityHash[:])
		return false, 0, errors.New("GetConversationMessageViewIndex called with invalid theirIdentityHash: " + theirIdentityHashHex)
	}

	if (myIdentityType != theirIdentityType){
		return false, 0, errors.New("GetConversationMessageViewIndex called with mismatched my/their identityTypes.")
	}

	if (myIdentityType == "Host"){
		return false, 0, errors.New("GetConversationMessageViewIndex called with Host identityTypes.")
	}

	isValid := helpers.VerifyNetworkType(networkType)
	if (isValid == false){
		networkTypeString := helpers.ConvertByteToString(networkType)
		return false, 0, errors.New("GetConversationMessageViewIndex called with invalid networkType: " + networkTypeString)
	}

	networkTypeString := helpers.ConvertByteToString(networkType)

	conversationKey := myIdentityHashString + "+" + theirIdentityHashString + "@" + networkTypeString

	exists, viewIndexString, err := myConversationViewIndexesMapDatastore.GetMapEntry(conversationKey)
	if (err != nil) { return false, 0, err }
	if (exists == false) {
		return false, 0, nil
	}

	viewIndex, err := helpers.ConvertStringToInt(viewIndexString)
	if (err != nil) {
		return false, 0, errors.New("myConversationViewIndexesMapDatastore malformed: Contains invalid view index: " + viewIndexString)
	}

	return true, viewIndex, nil
}




