package git

import (
	"bytes"
	"fmt"
	"log/slog"
	"os/exec"
	"path/filepath"
	"time"
)

const gitPath = "/usr/bin/git"

func Clone(baseRepoPath, owner, name string) error {
	_, err := Git(baseRepoPath, "clone", AsUrl(owner, name), AsPath(owner, name))
	return err
}

func Pull(baseRepoPath, owner, name string) error {
	cwd := filepath.Join(baseRepoPath, AsPath(owner, name))
	_, err := Git(cwd, "pull")
	return err
}

func DiffInterval(repoPath string, since time.Time) (string, error) {
	sinceStr := since.Format(time.RFC3339)

	commitHashBytes, err := Git(repoPath, "log", "--before="+sinceStr, "-1", "--format=%H")
	if err != nil {
		return "", fmt.Errorf("failed to find commit before %s with %w", sinceStr, err)
	}
	commitHash := string(bytes.TrimSpace(commitHashBytes))
	if commitHash == "" {
		return "", fmt.Errorf("no commit found before or at %s in repository %s", sinceStr, repoPath)
	}

	diffBytes, err := Git(repoPath, "diff", commitHash, "HEAD")
	if err != nil {
		return "", fmt.Errorf("failed to get diff from %s to HEAD: %w", commitHash, err)
	}

	return string(diffBytes), nil
}

func AsUrl(owner, name string) string {
	return fmt.Sprintf("http://github.com/%s/%s", owner, name)
}

func AsPath(owner, name string) string {
	return filepath.Join(owner, name)
}

func Git(cwd string, args ...string) ([]byte, error) {
	slog.Info("executing git command", "args", args)
	cmd := exec.Command(gitPath, args...)
	cmd.Dir = cwd
	stdout, err := cmd.Output()
	if err != nil {
		return nil, fmt.Errorf("failed to execute '%s %s' with %w", gitPath, args, err)
	}
	return stdout, nil
}

Graph