package xrpc

import (
	"bytes"
	"fmt"
	"net/http"
	"os/exec"
	"strings"

	"github.com/bluesky-social/indigo/atproto/atclient"
	"github.com/bluesky-social/indigo/atproto/syntax"
)

func (x *Xrpc) FormatPatch(w http.ResponseWriter, r *http.Request) {
	var (
		repoQuery = r.URL.Query().Get("repo")
		from      = r.URL.Query().Get("from")
		to        = r.URL.Query().Get("to")
	)

	repo, err := syntax.ParseDID(repoQuery)
	if err != nil {
		writeJson(w, http.StatusBadRequest, atclient.ErrorBody{Name: "BadRequest", Message: fmt.Sprintf("repo parameter invalid: %s", repoQuery)})
		return
	}

	// reject leading dashes so user input can't be parsed as git flags
	if from == "" || to == "" || strings.HasPrefix(from, "-") || strings.HasPrefix(to, "-") {
		writeJson(w, http.StatusBadRequest, atclient.ErrorBody{Name: "BadRequest", Message: "missing or invalid from/to parameter"})
		return
	}

	l := x.logger.With("method", "git.formatPatch", "repo", repo, "from", from, "to", to)
	l.Debug("request")

	ctx := r.Context()

	repoPath, err := x.makeRepoPath(ctx, repo)
	if err != nil {
		writeJson(w, http.StatusNotFound, atclient.ErrorBody{Name: "RepoNotFound", Message: fmt.Sprintf("unknown repository: %q", repo)})
		return
	}

	cmd := exec.CommandContext(ctx, "git", "-C", repoPath, "format-patch", "--stdout", fmt.Sprintf("%s..%s", from, to))
	stderr := new(bytes.Buffer)
	cmd.Stderr = stderr

	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	cmd.Stdout = w
	if err := cmd.Run(); err != nil {
		l.Error("running format-patch", "err", err, "stderr", stderr.String())
		w.WriteHeader(http.StatusInternalServerError)
	}
}
