
// createReports provides a function to create reports.

package createReports

// We encode each attribute as an integer in MessagePack:
// ReportVersion = 1
// CreationTime = 3
// ReportedHash = 4
// Reason = 5
// MessageCipherKey = 6

//TODO: Encode ReportType value as a number to save space

import "seekia/internal/appValues"
import "seekia/internal/helpers"
import "seekia/internal/moderation/readReports"
import "seekia/internal/encoding"

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

import "time"
import "errors"

//Outputs:
//	-[]byte: Report bytes
//	-error
func CreateReport(reportMap map[string]string)([]byte, error){

	reportVersion := appValues.GetReportVersion()

	reportNetworkTypeString, exists := reportMap["NetworkType"]
	if (exists == false){
		return nil, errors.New("CreateReport called with reportMap missing NetworkType")
	}

	reportNetworkType, err := helpers.ConvertNetworkTypeStringToByte(reportNetworkTypeString)
	if (err != nil){
		return nil, errors.New("CreateReport called with reportMap containing invalid NetworkType: " + reportNetworkTypeString)
	}

	creationTime := time.Now().Unix()

	reportedHashString, exists := reportMap["ReportedHash"]
	if (exists == false){
		return nil, errors.New("CreateReport called with reportMap missing reportedHash")
	}

	reportedHash, reportType, err := helpers.ReadReportedHashString(reportedHashString)
	if (err != nil){
		return nil, errors.New("CreateReport called with reportMap containing invalid ReportedHash: " + reportedHashString + ". Reason: " + err.Error())
	}

	reportVersionEncoded, err := encoding.EncodeMessagePackBytes(reportVersion)
	if (err != nil){ return nil, err }

	reportNetworkTypeEncoded, err := encoding.EncodeMessagePackBytes(reportNetworkType)
	if (err != nil){ return nil, err }

	creationTimeEncoded, err := encoding.EncodeMessagePackBytes(creationTime)
	if (err != nil){ return nil, err }

	reportedHashEncoded, err := encoding.EncodeMessagePackBytes(reportedHash)
	if (err != nil){ return nil, err }

	reportContentMap := map[int]messagepack.RawMessage{
		1: reportVersionEncoded,
		2: reportNetworkTypeEncoded,
		3: creationTimeEncoded,
		4: reportedHashEncoded,
	}

	reason, exists := reportMap["Reason"]
	if (exists == true){

		reasonEncoded, err := encoding.EncodeMessagePackBytes(reason)
		if (err != nil){ return nil, err }

		reportContentMap[5] = reasonEncoded
	}

	if (reportType == "Message"){

		messageCipherKeyString, exists := reportMap["MessageCipherKey"]
		if (exists == false){
			return nil, errors.New("CreateReport called with message reportMap missing MessageCipherKey")
		}
		messageCipherKey, err := encoding.DecodeHexStringToBytes(messageCipherKeyString)
		if (err != nil){
			return nil, errors.New("CreateReport called with reportMap containing invalid messageCipherKey: Not Hex: " + messageCipherKeyString)
		}

		if (len(messageCipherKey) != 32){
			return nil, errors.New("CreateReport called with reportMap containing invalid messageCipherKey: Invalid length: " + messageCipherKeyString)
		}

		messageCipherKeyEncoded, err := encoding.EncodeMessagePackBytes(messageCipherKey)
		if (err != nil){ return nil, err }

		reportContentMap[6] = messageCipherKeyEncoded
	}

	reportBytes, err := encoding.EncodeMessagePackBytes(reportContentMap)
	if (err != nil) { return nil, err }

	isValid, err := readReports.VerifyReport(reportBytes)
	if (err != nil) { return nil, err }
	if (isValid == false){
		return nil, errors.New("Failed to create report: Invalid result.")
	}

	return reportBytes, nil
}



