// Copyright 2023 wanderer <a_mirre at utb dot cz>
// SPDX-License-Identifier: GPL-3.0-or-later

package report

import (
	_ "embed"
	"fmt"
	"io"
	"log"
	"os"
	"text/template"
	"time"
)

const (
	outPrefix = "out/"
	texDir    = "tex/"
	picsDir   = "pics/"
)

var (
	//go:embed report_base.tmpl
	tmplReportBaseFile []byte
	//go:embed meta.sty
	metaSty []byte
	//go:embed report.tmpl
	tmplReportFile []byte
)

func GetOutPrefix() string {
	return outPrefix
}

// GetPicsDirPrefix returns the path to the folder meant for tex files.
func GetTexDir() string {
	return outPrefix + texDir
}

// GetPicsDirPrefix returns the path to the folder meant for plot pics.
func GetPicsDir() string {
	return outPrefix + picsDir
}

func emitReportBaseTex() error {
	fname := GetTexDir() + "report_base.tex"

	f, err := os.Create(fname)
	if err != nil {
		log.Fatal(err)
	}

	defer f.Close()

	tmplReportBase := template.New("report_base")
	tmplReportBase = template.Must(tmplReportBase.Parse(string(tmplReportBaseFile)))

	err = tmplReportBase.Execute(f, struct {
		Timestamp time.Time
	}{
		Timestamp: time.Now(),
	})

	if err != nil {
		log.Println(err)
	}

	return err
}

func emitReportTex(fname string) error {
	f, err := os.Create(fname)
	if err != nil {
		log.Fatal(err)
	}

	defer f.Close()

	tmplReport := template.New("report")
	tmplReport = template.Must(tmplReport.Parse(string(tmplReportFile)))

	err = tmplReport.Execute(f, struct {
		Timestamp time.Time
	}{
		Timestamp: time.Now(),
	})

	if err != nil {
		log.Println(err)
	}

	return err
}

func saveMetaSty() error {
	// save meta.sty
	fmeta, err := os.Create("meta.sty")
	if err != nil {
		log.Fatal(err)
	}

	defer fmeta.Close()

	_, err = fmeta.Write(metaSty)

	return err
}

// SaveAndPrint emits the tex files necessary to compile the report in full
// (report.tex, meta.sty) and prints the report.tex file to console.
func SaveAndPrint(doPrint bool) {
	err := emitReportBaseTex()
	if err != nil {
		log.Fatal(err)
	}

	reportFname := "report.tex"

	err = emitReportTex(reportFname)
	if err != nil {
		log.Fatal(err)
	}

	err = saveMetaSty()
	if err != nil {
		log.Fatal(err)
	}

	if doPrint {
		fmt.Fprint(os.Stderr, "\n* printing the report...\n\n")

		fh, err := os.Open(reportFname)
		if err != nil {
			log.Fatal(err)
		}

		_, err = io.Copy(os.Stdout, fh)
		if err != nil {
			log.Fatal(err)
		}
	}
}
