package internal

import (
	"embed"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
)

type KoshoHook string

const (
	// Runs after a worktree is created
	HOOK_CREATE KoshoHook = "create"

	// Runs before running a command inside a worktree
	HOOK_RUN KoshoHook = "run"
)

var (
	//go:embed sample-hooks
	KoshoHooks embed.FS
)

func writeKoshoHookSamples(hookDir string) error {
	samples, err := KoshoHooks.ReadDir("sample-hooks")
	if err != nil {
		return fmt.Errorf("failed to read sample hooks directory: %w", err)
	}
	for _, sample := range samples {
		srcPath := filepath.Join("sample-hooks", sample.Name())
		destPath := filepath.Join(hookDir, sample.Name())
		data, err := KoshoHooks.ReadFile(srcPath)
		if err != nil {
			return fmt.Errorf("failed to read sample hook file %s: %w", srcPath, err)
		}
		if err := writeFileIfNotExists(destPath, data, 0755); err != nil {
			return fmt.Errorf("failed to write sample hook file %s: %w", destPath, err)
		}
	}

	return nil
}

// RunKoshoHook executes a kosho hook script if it exists, running it in the worktree directory.
func RunKoshoHook(worktree *KoshoWorktree, hook KoshoHook, extraEnv ...string) error {
	hookFile := worktree.KoshoDir.HookPath(hook)

	// abort if hook does not exist
	if _, err := os.Stat(hookFile); os.IsNotExist(err) {
		return nil
	} else if err != nil {
		return fmt.Errorf("failed to stat hook file %s: %w", hookFile, err)
	}

	// try to run the hook in the worktree directory
	cmd := exec.Command(hookFile)
	cmd.Dir = worktree.WorktreePath()
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Env = append(os.Environ(),
		"KOSHO_HOOK="+string(hook),
		"KOSHO_WORKTREE="+worktree.WorktreeName,
		"KOSHO_REPO="+worktree.KoshoDir.RepoPath(),
		"KOSHO_WORKTREE_PATH="+worktree.WorktreePath(),
	)
	cmd.Env = append(cmd.Env, extraEnv...)

	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to run hook %s: %w", hook, err)
	}
	return nil
}
