package gitpb

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

// files   : a list of files to save ["go.mod", "go.sum"]
// refname : could be "master" or "v0.1.5" or "a605119c2cc41"
// del     : true means empty out existing notes, otherwise append
func (repo *Repo) AutogenSave(files []string, refname string, del bool) error {
	if del {
		cmd := []string{"git", "notes", "show", refname}
		if err := repo.StrictRun(cmd); err != nil {
			// if there are not any notes, no need to remove them
		} else {
			cmd := []string{"git", "notes", "remove", refname}
			if err := repo.StrictRun(cmd); err != nil {
				return err
			}
		}
	}
	for _, fname := range files {
		autotag := "// `autogen:" + fname + "`"
		cmd := []string{"git", "notes", "append", "-m", autotag, refname}
		if err := repo.StrictRun(cmd); err != nil {
			return err
		}
		cmd = []string{"git", "notes", "append", "-F", fname, refname}
		if err := repo.StrictRun(cmd); err != nil {
			return err
		}
	}
	// a tag with a blank name indicates the end of the autogen file or files
	autotag := "// `autogen:`"
	cmd := []string{"git", "notes", "append", "-m", autotag, refname}
	if err := repo.StrictRun(cmd); err != nil {
		return err
	}
	return nil
}

// restores files from git metadata (notes)
func (repo *Repo) AutogenRestore(refname string) error {
	var cmd []string
	if refname == "" {
		cmd = []string{"git", "notes", "show"}
	} else {
		cmd = []string{"git", "notes", "show", refname}
	}

	result := repo.Run(cmd)
	if result.Exit != 0 {
		return errors.New(fmt.Sprint("git notes show returned ", result.Exit))
	}
	if result.Error != nil {
		return result.Error
	}
	if len(result.Stdout) == 0 {
		return nil
	}

	var newf *os.File
	var err error
	var body string
	for _, line := range result.Stdout {
		if strings.HasPrefix(line, "// `autogen:") {
			if newf != nil {
				fmt.Fprintln(newf, strings.TrimSpace(body))
				newf.Close()
				newf = nil
				body = ""
			}
			fbase := strings.TrimPrefix(line, "// `autogen:")
			fbase = strings.TrimSpace(fbase)
			fbase = strings.TrimSuffix(fbase, "`")
			// if line == // `autogen:`  , then the filename is blank
			if fbase != "" {
				fname := filepath.Join(filepath.Join(repo.FullPath, fbase))
				newf, err = os.OpenFile(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
				if err != nil {
					return err
				}
			}
			continue
		}
		body += line + "\n"
	}
	if newf != nil {
		fmt.Fprintln(newf, strings.TrimSpace(body))
		newf.Close()
	}
	return nil
}