package main

import (
	"bytes"
	"errors"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"gopkg.in/yaml.v3"
)

type contentRequirement struct {
	content string
	data    requirement
}

func splitYamlParts(content []byte) (error, contentRequirement) {

	origin := string(content)

	meta := ""
	text := ""

	before, remaining, found := strings.Cut(origin, "---")
	if !found {

		t := strings.TrimSpace(origin)
		if len(t) == 0 {
			return errors.New("the file is empty"), contentRequirement{
				content: origin,
				data:    requirement{},
			}
		}

		return errors.New("the file does not contain a definition block"), contentRequirement{
			content: origin,
			data:    requirement{},
		}
	}

	text += before

	a, b, found := strings.Cut(remaining, "\n...")
	if !found {
		a, b, found = strings.Cut(remaining, "\n---")

		if !found {

			a, b, found = strings.Cut(remaining, "...")

			if !found {

				a, b, found = strings.Cut(remaining, "---")

				if !found {
					return errors.New("the file does not contain a definition block"), contentRequirement{}
				}

			}
		}

	}

	meta = a
	text += b

	t, err := template.New("overview").Parse(text)
	if err != nil {
		return err, contentRequirement{}
	}

	var node yaml.Node
	err = yaml.Unmarshal([]byte(meta), &node)
	if err != nil {
		return err, contentRequirement{}
	}

	data := requirement{}
	err = node.Decode(&data)
	if err != nil {
		return err, contentRequirement{}
	}

	tempItem := []Item{}
	for i, _ := range data.Items {

		if data.Items[i].ID == "" {
			continue
		}

		data.Items[i].ID = data.ID + "-" + data.Items[i].ID
		tempItem = append(tempItem, data.Items[i])
	}

	data.Items = tempItem

	p := []Privacy{}
	for i, _ := range data.Privacy {
		if data.Privacy[i].ID == "" {
			continue
		}

		data.Privacy[i].ID = data.ID + "-" + data.Privacy[i].ID
		p = append(p, data.Privacy[i])

	}

	data.Privacy = p

	req := contentRequirement{}
	req.data = data

	req.data.OriginNode = &node
	req.data.OriginText = text

	var buffer bytes.Buffer
	err = t.Execute(&buffer, data)
	if err != nil {
		printError(err.Error())
		return err, contentRequirement{}
	}

	req.content = buffer.String()

	return nil, req

}

func translateHeaders(columns []string) []string {

	result := []string{}

	for _, column := range columns {
		result = append(result, printer.Sprintf(column))
	}

	return result

}

func getGitDirectory() (string, error) {

	path := config.Path

	fileInfo, err := os.Stat(path)
	if err != nil {
		return "", err
	}

	if !fileInfo.IsDir() {
		path = filepath.Dir(path)
	}

	return findGitDirectory(path)
}

func findGitDirectory(path string) (string, error) {

	if path == "" {
		return "", noGitRepositoryError
	}

	if volume := filepath.VolumeName(path); volume != "" {
		if volume == path {
			return "", noGitRepositoryError
		}
	} else {
		if path == "/" {
			return "", noGitRepositoryError
		}
	}

	if !exists(filepath.Join(path, ".git")) {
		return findGitDirectory(filepath.Dir(path))
	}

	return path, nil

}

func exists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}

	if os.IsNotExist(err) {
		return false
	}

	printErrorAndExit(0, err.Error())

	return false
}