package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"

	"git.sandpoints.org/Drawwell/SandpointsGitHook/giq"
)

var (
	version = "21.03.02"
)

func check(e error) {
	if e != nil {
		fmt.Printf("\nGit hook version: %s\n~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n", version)
		log.Fatal(e)
		panic(e)
	}
}

type Hugo struct {
	CatalogName    string
	CatalogPrefix  string
	SourceDir      string
	DestinationDir string
	PublicHTMLName string
}

type Hook struct {
	Context        string
	Publish        bool
	Offline        bool
	Gogit          bool
	Stdinput       string
	ExecutablePath string
	PublicHTMLPath string
}

func gitExePath(hook *Hook) string {
	gexe := "git"
	if runtime.GOOS == "windows" {
		gexe = "git.exe"
	}
	gpath, err := exec.LookPath(gexe)
	check(err)
	if gpath != "" {
		hook.Gogit = false
		return gpath
	} else {
		hook.Gogit = true
		return ""
	}
}

func hookContext(hook *Hook) {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	if scanner.Text() == "" {
		hook.Context = "PostCommit"
	} else if strings.HasPrefix(scanner.Text(), "sandpoints-ext") {
		revs := strings.Fields(scanner.Text())
		if revs[1] == "publish" {
			hook.Publish = true
		}
		if revs[2] == "offline" {
			hook.Offline = true
		}
		if revs[3] == "file" {
			hook.Context = "SandpointsFileProtocol"
		}
		if revs[3] == "http" {
			hook.Context = "SandpointsHTTPProtocol"
		}
	} else {
		// it only handles gitea use case if not Local or sandpoints-ext
		hook.Context = "PostReceive"
		hook.Stdinput = scanner.Text()
	}
}

func hugoLogs(logLines string, lines []string) string {
	logLines = logLines + "~~~~~~~~~~ Hugo's logs ~~~~~~~~~~\n"
	for _, d := range lines {
		logLines = logLines + d + "\n"

	}
	logLines = logLines + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
	return logLines
}

func main() {
	// init global struct/variables
	var hook *Hook
	var hugo *Hugo
	var git giq.Git
	var giqi giq.Giqi

	hook = new(Hook)
	hugo = new(Hugo)

	hook.Publish = false
	hook.Gogit = true
	hook.PublicHTMLPath = filepath.Join("/var", "www", "html", "sandpoints")

	logLines := ""
	// hookExe, err := os.Executable()
	// check(err)
	// hook.ExecutablePath = filepath.Dir(hookExe)
	hook.ExecutablePath = "/home/m/Downloads/SimpleSandpoints/.git/hooks"
	// hook.ExecutablePath = "/home/m/gitea-repositories/sandpoints/dev.git/hooks/post-receive.d"
	hookContext(hook)
	gitPath := gitExePath(hook)
	giqi = &giq.Gogit{}
	// enforce go-git if mocking hook.ExecutablePath
	if hook.Gogit {
		// DEFAULT but enforce sysgit if mocking hook.ExecutablePath
		// if !hook.Gogit {
		giqi = &giq.Sysgit{}
	}
	fmt.Println(giqi.Whoami())
	git = giqi.GitStruct(hook.ExecutablePath, hook.Context, hook.Stdinput, gitPath)
	fmt.Printf("%#v\n", git)
	hook.Publish = git.Publish
	hugo.SourceDir = git.RepoPath
	// hugo.DestinationDir =

	if git.IsBare {
		giqi.AddBareWorktree(git.RepoPath, git.IndexPath, git.Worktree, gitPath)
		defer giqi.RemoveBareWorktree(git.RepoPath, git.IndexPath, git.Worktree, gitPath)
		hugo.SourceDir = git.TmpRepoPath

		tree, err := exec.Command("/usr/bin/tree", git.TmpRepoPath).Output()
		check(err)
		fmt.Println(string(tree))
	}

	hugoContext(hugo, git.RepoPath)
	fmt.Printf("%#v\n", hugo)

	hugoRender(hugo, hook.Offline)
	cleanUpPublicHTML(hugo, hook)
	copyToPublicHTML(hugo, hook)

	_ = hugo
	_ = logLines
}
