
// myProfileStatus provides functions to check if a user's profile is active on the network

package myProfileStatus

// For a profile to be active, multiple conditions must be met:
//	1. User's identity is funded
//	2. User's broadcast profile exists (the user has uploaded their profile to the network)
//	3. User's broadcast profile is funded (if profileType == "Mate")
//	4. User's broadcast profile is not disabled
//		A disabled profile will exist on the network until the identity's balance expires, or the maximum profile existence time has passed
//	5. User's broadcast profile Disabled status matches their local profile.

import "seekia/internal/helpers"
import "seekia/internal/moderation/myIdentityScore"
import "seekia/internal/myIdentity"
import "seekia/internal/network/myBroadcasts"
import "seekia/internal/network/myFundedStatus"
import "seekia/internal/network/myIdentityBalance"
import "seekia/internal/parameters/getParameters"
import "seekia/internal/profiles/myLocalProfiles"

import "time"
import "errors"

//Outputs:
//	-bool: My identity exists
//	-bool: My profile is active
//	-error
func GetMyProfileIsActiveStatus(myIdentityHash [16]byte, networkType byte)(bool, bool, error){

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

	isMine, myIdentityType, err := myIdentity.CheckIfIdentityHashIsMine(myIdentityHash)
	if (err != nil) { return false, false, err }
	if (isMine == false){
		return false, false, nil
	}

	identityExists, profileExists, broadcastProfileHash, getAnyAttributeFromMyBroadcastProfile, err := myBroadcasts.GetRetrieveAnyAttributeFromMyBroadcastProfileFunction(myIdentityHash, networkType)
	if (err != nil) { return false, false, err }
	if (identityExists == false) {
		return false, false, errors.New("My identity not found after being found already.")
	}
	if (profileExists == false){
		// There is no broadcast profile.
		// Profile has never been broadcasted from this device.
		// Profile is not active.
		return true, false, nil	
	}

	attributeExists, _, broadcastProfileIsDisabled, err := getAnyAttributeFromMyBroadcastProfile("Disabled")
	if (err != nil) { return false, false, err }
	if (attributeExists == true && broadcastProfileIsDisabled == "Yes"){
		// Current broadcast profile is disabled.
		// Profile is not active.

		return true, false, nil
	}

	// We check if the local profile is disabled.

	exists, iAmDisabled, err := myLocalProfiles.GetProfileData(myIdentityType, "Disabled")
	if (err != nil) { return false, false, err }
	if (exists == true && iAmDisabled == "Yes"){
		// The current broadcast profile is not disabled, but the local profile is.
		// This should only occur if the profile was disabled on a different network,
		//		funding the new profile failed, or is currently being attempted.
		// We check for this because we don't want to allow the sending of messages when this occurs

		// TODO: Perform the automatic updating and broadcasting of disabled profiles when the user
		//		disables their profile and switches to a different networkType

		return true, false, nil
	}

	// Now we check if profile is inactive due to lack of identity balance funds, or expiration
	// Moderator profiles never expire

	if (myIdentityType == "Mate" || myIdentityType == "Host"){

		attributeExists, _, creationTimeString, err := getAnyAttributeFromMyBroadcastProfile("CreationTime")
		if (err != nil) { return false, false, err }
		if (attributeExists == false) {
			return false, false, errors.New("Malformed broadcast profile: Missing CreationTime.")
		}

		creationTimeInt64, err := helpers.ConvertCreationTimeStringToInt64(creationTimeString)
		if (err != nil) {
			return false, false, errors.New("Malformed broadcast profile: Contains invalid CreationTime: " + creationTimeString)
		}
	
		identityExists, myBalanceIsSufficient, _, err := myIdentityBalance.GetMyIdentityBalanceStatus(myIdentityHash, networkType)
		if (err != nil){ return false, false, err }
		if (identityExists == false) {
			return false, false, errors.New("My identity not found after being found already.")
		}
		if (myBalanceIsSufficient == false){
			return true, false, nil
		}

		if (myIdentityType == "Mate" || myIdentityType == "Host"){

			// We check to see if profile has expired from the network
			// Moderator profiles never expire

			getMaximumExistenceDuration := func()(int64, error){

				if (myIdentityType == "Mate"){
	
					_, maximumExistenceTime, err := getParameters.GetMateProfileMaximumExistenceDuration(networkType)
					if (err != nil){ return 0, err }

					return maximumExistenceTime, nil
				}

				_, maximumExistenceTime, err := getParameters.GetHostProfileMaximumExistenceDuration(networkType)
				if (err != nil) { return 0, err }
	
				return maximumExistenceTime, nil
			}

			maximumExistenceDuration, err := getMaximumExistenceDuration()
			if (err != nil){ return false, false, err }

			currentTime := time.Now().Unix()
			
			timeElapsed := currentTime - creationTimeInt64

			if (maximumExistenceDuration <= timeElapsed){
				// Profile has expired from network
				return true, false, nil
			}
		}
	}
	
	if (myIdentityType == "Moderator"){

		// We check if identity score is sufficient

		identityExists, _, scoreIsSufficient, _, _, err := myIdentityScore.GetMyIdentityScore()
		if (err != nil) { return false, false, err }
		if (identityExists == false) {
			return false, false, errors.New("My identity not found after being found.")
		}
		
		if (scoreIsSufficient == false){
			return true, false, nil
		}
	}

	if (myIdentityType == "Mate"){

		// We make sure profile is funded

		statusIsKnown, profileIsFunded, _, err := myFundedStatus.CheckIfMyMateProfileIsFunded(broadcastProfileHash)
		if (err != nil) { return false, false, err }
		if (statusIsKnown == false || profileIsFunded == false){
			return true, false, nil
		}	
	}

	// Profile should be active on the network!

	return true, true, nil
}





