
// hostRanges provides functions to retrieve a host's hosted ranges from their profile map

package hostRanges

import "seekia/internal/byteRange"
import "seekia/internal/encoding"
import "seekia/internal/messaging/inbox"
import "seekia/internal/profiles/readProfiles"

import messagepack "github.com/vmihailenco/msgpack/v5"

import "errors"

//Outputs:
//	-bool: Host is hosting any provided identityType content
//	-[16]byte: Hosted Identity hash range start
//	-[16]byte: Hosted Identity hash range end
//	-error
func GetHostedIdentityHashRangeFromHostRawProfileMap(hostRawProfileMap map[int]messagepack.RawMessage, identityType string)(bool, [16]byte, [16]byte, error){

	if (identityType != "Mate" && identityType != "Host" && identityType != "Moderator"){
		return false, [16]byte{}, [16]byte{}, errors.New("GetHostedIdentityHashRangeFromHostRawProfileMap called with invalid identityType: " + identityType)
	}

	hostIsDisabled, _, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "Disabled")
	if (err != nil) { return false, [16]byte{}, [16]byte{}, err }
	if (hostIsDisabled == true){
		return false, [16]byte{}, [16]byte{}, nil
	}

	exists, hostingIdentityTypeContent, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "Hosting" + identityType + "Content")
	if (err != nil) { return false, [16]byte{}, [16]byte{}, err }
	if (exists == false){
		return false, [16]byte{}, [16]byte{}, errors.New("Database corrupt: Contains Host profile map missing Hosting" + identityType + "Content")
	}

	if (hostingIdentityTypeContent != "Yes"){
		return false, [16]byte{}, [16]byte{}, nil
	}
	if (identityType != "Mate"){
		// Hosts must host either all or none of Host/Moderator content

		minimumIdentityBound, maximumIdentityBound := byteRange.GetMinimumMaximumIdentityHashBounds()

		return true, minimumIdentityBound, maximumIdentityBound, nil
	}

	exists, theirMateHostRangeStartString, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "MateIdentitiesRangeStart")
	if (err != nil) { return false, [16]byte{}, [16]byte{}, err }
	if (exists == false){
		return false, [16]byte{}, [16]byte{}, errors.New("Database corrupt: Contains host profile missing MateIdentitiesRangeStart")
	}

	exists, theirMateHostRangeEndString, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "MateIdentitiesRangeEnd")
	if (err != nil) { return false, [16]byte{}, [16]byte{}, err }
	if (exists == false){
		return false, [16]byte{}, [16]byte{}, errors.New("Database corrupt: Contains host profile missing MateIdentitiesRangeEnd")
	}

	theirMateHostRangeStartBytes, err := encoding.DecodeHexStringToBytes(theirMateHostRangeStartString)
	if (err != nil){
		return false, [16]byte{}, [16]byte{}, errors.New("Database corrupt: Contains host profile containing invalid MateIdentitiesRangeStart: Not Hex: " + theirMateHostRangeStartString)
	}

	if (len(theirMateHostRangeStartBytes) != 16){
		return false, [16]byte{}, [16]byte{}, errors.New("Database corrupt: Contains host profile containing invalid MateIdentitiesRangeStart: Invalid length: " + theirMateHostRangeStartString)
	}

	theirMateHostRangeStart := [16]byte(theirMateHostRangeStartBytes)

	theirMateHostRangeEndBytes, err := encoding.DecodeHexStringToBytes(theirMateHostRangeEndString)
	if (err != nil){
		return false, [16]byte{}, [16]byte{}, errors.New("Database corrupt: Contains host profile containing invalid MateIdentitiesRangeEnd: Not Hex: " + theirMateHostRangeEndString)
	}

	if (len(theirMateHostRangeEndBytes) != 16){
		return false, [16]byte{}, [16]byte{}, errors.New("Database corrupt: Contains host profile containing invalid MateIdentitiesRangeEnd: Invalid length: " + theirMateHostRangeEndString)
	}

	theirMateHostRangeEnd := [16]byte(theirMateHostRangeEndBytes)

	return true, theirMateHostRangeStart, theirMateHostRangeEnd, nil
}


//Outputs:
//	-bool: Host is hosting any messages
//	-[10]byte: Hosted message Inbox range start
//	-[10]byte: Hosted message inbox range end
//	-error
func GetHostedMessageInboxesRangeFromHostRawProfileMap(hostRawProfileMap map[int]messagepack.RawMessage)(bool, [10]byte, [10]byte, error){

	hostIsDisabled, _, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "Disabled")
	if (err != nil) { return false, [10]byte{}, [10]byte{}, err }
	if (hostIsDisabled == true){
		return false, [10]byte{}, [10]byte{}, nil
	}

	exists, hostingMessages, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "HostingMessages")
	if (err != nil) { return false, [10]byte{}, [10]byte{}, err }
	if (exists == false) {
		return false, [10]byte{}, [10]byte{}, errors.New("Database corrupt: Contains host profile missing HostingMessages")
	}
	if (hostingMessages != "Yes"){
		return false, [10]byte{}, [10]byte{}, nil
	}

	exists, theirInboxHostRangeStartString, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "MessageInboxesRangeStart")
	if (err != nil) { return false, [10]byte{}, [10]byte{}, err }
	if (exists == false){
		return false, [10]byte{}, [10]byte{}, errors.New("Database corrupt: Contains host profile missing MessageInboxesRangeStart")
	}

	exists, theirInboxHostRangeEndString, err := readProfiles.GetFormattedProfileAttributeFromRawProfileMap(hostRawProfileMap, "MessageInboxesRangeEnd")
	if (err != nil) { return false, [10]byte{}, [10]byte{}, err }
	if (exists == false){
		return false, [10]byte{}, [10]byte{}, errors.New("Database corrupt: Contains host profile missing MessageInboxesRangeEnd")
	}

	theirInboxHostRangeStart, err := inbox.ReadInboxString(theirInboxHostRangeStartString)
	if (err != nil){
		return false, [10]byte{}, [10]byte{}, errors.New("Database corrupt: Contains host profile with invalid MessageInboxesRangeStart: " + theirInboxHostRangeStartString)
	}

	theirInboxHostRangeEnd, err := inbox.ReadInboxString(theirInboxHostRangeEndString)
	if (err != nil){
		return false, [10]byte{}, [10]byte{}, errors.New("Database corrupt: Contains host profile with invalid MessageInboxesRangeEnd: " + theirInboxHostRangeEndString)
	}

	return true, theirInboxHostRangeStart, theirInboxHostRangeEnd, nil
}



