
// myInbox provides functions to get a user's public and secret inboxes

package myInbox

import "seekia/internal/encoding"
import "seekia/internal/helpers"
import "seekia/internal/myIdentity"
import "seekia/internal/messaging/inbox"
import "seekia/internal/messaging/mySecretInboxes"

import "errors"


// Returns all inboxes that we want to download messages from
// It will omit inboxes that are old enough that they have no messages, or ones we have checked sufficiently
func GetAllMyActiveInboxes(myIdentityHash [16]byte, networkType byte)([][10]byte, error){

	myPublicInbox, err := inbox.GetPublicInboxFromIdentityHash(myIdentityHash)
	if (err != nil) {
		myIdentityHashHex := encoding.EncodeBytesToHexString(myIdentityHash[:])
		return nil, errors.New("GetAllMyActiveInboxes called with invalid identity hash: " + myIdentityHashHex)
	}

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

	myInboxesList := [][10]byte{myPublicInbox}

	myActiveSecretInboxesList, err := mySecretInboxes.GetAllMyActiveSecretInboxes(myIdentityHash, networkType)
	if (err != nil) { return nil, err }

	myInboxesList = append(myInboxesList, myActiveSecretInboxesList...)

	return myInboxesList, nil
}

// Returns all inboxes, even ones we have already sufficiently checked
// Will not return inboxes for users I have blocked
func GetAllMyInboxes(myIdentityHash [16]byte, networkType byte)([][10]byte, error){

	myPublicInbox, err := inbox.GetPublicInboxFromIdentityHash(myIdentityHash)
	if (err != nil) {
		myIdentityHashHex := encoding.EncodeBytesToHexString(myIdentityHash[:])
		return nil, errors.New("GetAllMyInboxes called with invalid identity hash: " + myIdentityHashHex)
	}

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

	myInboxesList := [][10]byte{myPublicInbox}

	mySecretInboxesList, err := mySecretInboxes.GetAllMySecretInboxes(myIdentityHash, networkType)
	if (err != nil) { return nil, err }

	myInboxesList = append(myInboxesList, mySecretInboxesList...)

	return myInboxesList, nil
}


//Outputs:
//	-bool: Inbox is mine
//	-string: Identity type of inbox
//	-error
func CheckIfInboxIsMine(inputInbox [10]byte, networkType byte)(bool, string, error){

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

	chatIdentityTypesList := []string{"Mate", "Moderator"}

	for _, identityType := range chatIdentityTypesList{

		myIdentityFound, myIdentityHash, err := myIdentity.GetMyIdentityHash(identityType)
		if (err != nil) { return false, "", err }
		if (myIdentityFound == false){
			continue
		}

		myInboxesList, err := GetAllMyInboxes(myIdentityHash, networkType)
		if (err != nil) { return false, "", err }

		for _, inbox := range myInboxesList{

			if (inbox == inputInbox){
				return true, identityType, nil
			}
		}
	}
	
	return false, "", nil
}


//Outputs:
//	-bool: Inbox found
//	-[16]byte: Inbox My Identity Hash
//	-[32]byte: inbox doubledSealedKeys sealer key
//	-bool: Inbox is secret
//	-byte: Inbox network type (if inbox is secret)
//	-[16]byte: Conversation recipient (if inbox is secret)
//	-error
func GetMyInboxInfo(inputInbox [10]byte)(bool, [16]byte, [32]byte, bool, byte, [16]byte, error){

	chatIdentityTypesList := []string{"Mate", "Moderator"}

	for _, identityType := range chatIdentityTypesList{

		myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash(identityType)
		if (err != nil) { return false, [16]byte{}, [32]byte{}, false, 0, [16]byte{}, err }
		if (myIdentityExists == false){
			continue
		}

		myPublicInbox, err := inbox.GetPublicInboxFromIdentityHash(myIdentityHash)
		if (err != nil) { return false, [16]byte{}, [32]byte{}, false, 0, [16]byte{}, err }

		if (inputInbox == myPublicInbox){

			doubleSealedKeysSealerKey, err := inbox.GetPublicInboxSealerKeyFromIdentityHash(myIdentityHash)
			if (err != nil) { return false, [16]byte{}, [32]byte{}, false, 0, [16]byte{}, err }

			return true, myIdentityHash, doubleSealedKeysSealerKey, false, 0, [16]byte{}, nil
		}
	}

	inboxFound, inboxMyIdentityHash, conversationRecipientIdentityHash, inboxNetworkType, secretInboxSealerKey, _, _, err := mySecretInboxes.GetMySecretInboxInfo(inputInbox)
	if (err != nil){ return false, [16]byte{}, [32]byte{}, false, 0, [16]byte{}, err }
	if (inboxFound == true){
		return true, inboxMyIdentityHash, secretInboxSealerKey, true, inboxNetworkType, conversationRecipientIdentityHash, nil
	}

	return false, [16]byte{}, [32]byte{}, false, 0, [16]byte{}, nil
}





