
// createSampleGeneticAnalyses.go is a utility used to create the sample genetic analyses.
// These are analyses which are shown in the GUI to demonstrate what genetic analyses look like.
// These analyses are stored in the /internal/genetics/sampleAnalyses folder.
// You must add 2 raw genome files to this folder before running the utility: Person1RawGenome.txt and Person2RawGenome.txt
// I added some cystic fibrosis variants to my raw genome files so that the sample analysis would show a non-zero offspring risk.

package main

import "seekia/internal/encoding"
import "seekia/internal/localFilesystem"
import "seekia/internal/genetics/createCoupleGeneticAnalysis"
import "seekia/internal/genetics/createPersonGeneticAnalysis"
import "seekia/internal/genetics/prepareRawGenomes"
import "seekia/internal/genetics/geneticReferences/locusMetadata"
import "seekia/internal/genetics/geneticReferences/monogenicDiseases"
import "seekia/internal/genetics/geneticReferences/polygenicDiseases"
import "seekia/internal/genetics/geneticReferences/traits"
import "seekia/internal/genetics/trainedPredictionModels"

import "errors"
import "log"


func main(){

	err := locusMetadata.InitializeLocusMetadataVariables()
	if (err != nil) {
		log.Println("InitializeLocusMetadataVariables failed: " + err.Error())
		return	
	}

	monogenicDiseases.InitializeMonogenicDiseaseVariables()

	err = polygenicDiseases.InitializePolygenicDiseaseVariables()
	if (err != nil) {
		log.Println("InitializePolygenicDiseaseVariables failed: " + err.Error())
		return
	}

	err = traits.InitializeTraitVariables()
	if (err != nil) {
		log.Println("InitializeTraitVariables failed: " + err.Error())
		return
	}

	err = trainedPredictionModels.InitializeTrainedPredictionModels()
	if (err != nil) {
		log.Println("InitializeTrainedPredictionModels failed: " + err.Error())
		return
	}

	//Outputs:
	//	-bool: File exists
	//	-[]prepareRawGenomes.RawGenomeWithMetadata: Person genomes list
	//	-string: Analysis string
	//	-error
	getPersonRawGenomeListAndAnalysis := func(personRawGenomeFilepath string, genomeIdentifierHex string)(bool, []prepareRawGenomes.RawGenomeWithMetadata, string, error){

		fileExists, personRawGenomeFileBytes, err := localFilesystem.GetFileContents(personRawGenomeFilepath)
		if (err != nil){ return false, nil, "", err }
		if (fileExists == false){
			return false, nil, "", nil
		}

		personRawGenomeFileString := string(personRawGenomeFileBytes)

		genomeIdentifier, err := encoding.DecodeHexStringTo16ByteArray(genomeIdentifierHex)
		if (err != nil) { return false, nil, "", err }

		genomeIsValid, rawGenomeWithMetadata, err := prepareRawGenomes.CreateRawGenomeWithMetadataObject(genomeIdentifier, personRawGenomeFileString)
		if (err != nil){ return false, nil, "", err }
		if (genomeIsValid == false){
			return false, nil, "", errors.New("Raw genome is invalid: " + personRawGenomeFilepath)
		}

		personGenomesList := []prepareRawGenomes.RawGenomeWithMetadata{rawGenomeWithMetadata}

		updateProgressFunction := func(_ int)error{
			return nil
		}

		checkIfProcessIsStoppedFunction := func()bool{
			return false
		}

		processCompleted, personGeneticAnalysis, err := createPersonGeneticAnalysis.CreatePersonGeneticAnalysis(personGenomesList, updateProgressFunction, checkIfProcessIsStoppedFunction)
		if (err != nil){
			return false, nil, "", errors.New("Failed to create person genetic analysis: " + err.Error())
		}
		if (processCompleted == false){
			return false, nil, "", errors.New("Failed to create person genetic analysis: Process did not complete.")
		}

		return true, personGenomesList, personGeneticAnalysis, nil
	}

	fileExists, person1GenomeList, person1GeneticAnalysis, err := getPersonRawGenomeListAndAnalysis("./Person1RawGenome.txt", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
	if (err != nil){
		log.Println(err.Error())
		return
	}
	if (fileExists == false){
		log.Println("Error: Person1RawGenome.txt does not exist.")
		log.Println("You must add this raw genome file to the createSampleGeneticAnalyses folder.")
		return
	}

	fileExists, person2GenomeList, person2GeneticAnalysis, err := getPersonRawGenomeListAndAnalysis("./Person2RawGenome.txt", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
	if (err != nil){
		log.Println(err.Error())
		return
	}
	if (fileExists == false){
		log.Println("Error: Person2RawGenome.txt does not exist.")
		log.Println("You must add this raw genome file to the createSampleGeneticAnalyses folder.")
		return
	}

	updateProgressFunction := func(_ int)error{
		return nil
	}

	checkIfProcessIsStoppedFunction := func()bool{
		return false
	}

	processCompleted, coupleGeneticAnalysis, err := createCoupleGeneticAnalysis.CreateCoupleGeneticAnalysis(person1GenomeList, person2GenomeList, updateProgressFunction, checkIfProcessIsStoppedFunction)
	if (err != nil){
		log.Println("Failed to create couple genetic analysis: " + err.Error())
		return
	}
	if (processCompleted == false){
		log.Println("Failed to create couple genetic analysis: Process did not complete.")
		return
	}

	err = localFilesystem.CreateOrOverwriteFile([]byte(person1GeneticAnalysis), "./", "SamplePerson1Analysis.messagepack")
	if (err != nil){
		log.Println(err.Error())
		return
	}
	err = localFilesystem.CreateOrOverwriteFile([]byte(person2GeneticAnalysis), "./", "SamplePerson2Analysis.messagepack")
	if (err != nil){
		log.Println(err.Error())
		return
	}

	err = localFilesystem.CreateOrOverwriteFile([]byte(coupleGeneticAnalysis), "./", "SampleCoupleAnalysis.messagepack")
	if (err != nil){
		log.Println(err.Error())
		return
	}

	log.Println("Successfully created sample genetic analyses!")
}


