
// myReadStatus provides functions to manage the read/unread status of chat conversations

package myReadStatus

//TODO: Add function to prune statuses for conversations with no messages

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

import "errors"

var myConversationReadUnreadStatusesMapDatastore *myMap.MyMap

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

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

	myConversationReadUnreadStatusesMapDatastore = newMyConversationReadUnreadStatusesMapDatastore

	return nil
}


func SetConversationReadUnreadStatus(myIdentityHash [16]byte, theirIdentityHash [16]byte, networkType byte, readOrUnread string)error{

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

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

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

	if (readOrUnread != "Read" && readOrUnread != "Unread") {
		return errors.New("SetConversationReadUnreadStatus called with invalid read/unread status: " + readOrUnread)
	}

	networkTypeString := helpers.ConvertByteToString(networkType)

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

	err = myConversationReadUnreadStatusesMapDatastore.SetMapEntry(conversationKey, readOrUnread)
	if (err != nil) { return err }

	return nil
}

func GetConversationReadUnreadStatus(myIdentityHash [16]byte, theirIdentityHash [16]byte, networkType byte)(string, error){

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

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

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

	networkTypeString := helpers.ConvertByteToString(networkType)

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

	exists, readOrUnread, err := myConversationReadUnreadStatusesMapDatastore.GetMapEntry(conversationKey)
	if (err != nil) { return "", err }
	if (exists == false) {
		return "Unread", nil
	}

	if (readOrUnread != "Read" && readOrUnread != "Unread"){
		return "", errors.New("myConversationReadUnreadStatusesMapDatastore malformed: Item contains invalid ReadOrUnread: " + readOrUnread)
	}

	return readOrUnread, nil
}


