// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

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

func cmdReword(args []string) {
	flags.Usage = func() {
		fmt.Fprintf(stderr(), "Usage: %s reword %s [commit...]\n",
			progName, globalFlags)
		exit(2)
	}
	flags.Parse(args)
	args = flags.Args()

	// Check that we understand the structure
	// before we let the user spend time editing messages.
	b := CurrentBranch()
	pending := b.Pending()
	if len(pending) == 0 {
		dief("reword: no commits pending")
	}
	if b.Name == "HEAD" {
		dief("reword: no current branch")
	}
	var last *Commit
	for i := len(pending) - 1; i >= 0; i-- {
		c := pending[i]
		if last != nil && !c.HasParent(last.Hash) {
			dief("internal error: confused about pending commit graph: parent %.7s vs %.7s", last.Hash, c.Parents)
		}
		last = c
	}

	headState := func() (head, branch string) {
		head = trim(cmdOutput("git", "rev-parse", "HEAD"))
		for _, line := range nonBlankLines(cmdOutput("git", "branch", "-l")) {
			if strings.HasPrefix(line, "* ") {
				branch = trim(line[1:])
				return head, branch
			}
		}
		dief("internal error: cannot find current branch")
		panic("unreachable")
	}

	head, branch := headState()
	if head != last.Hash {
		dief("internal error: confused about pending commit graph: HEAD vs parent: %.7s vs %.7s", head, last.Hash)
	}
	if branch != b.Name {
		dief("internal error: confused about pending commit graph: branch name %s vs %s", branch, b.Name)
	}

	// Build list of commits to be reworded.
	// Do first, in case there are typos on the command line.
	var cs []*Commit
	newMsg := make(map[*Commit]string)
	if len(args) == 0 {
		for _, c := range pending {
			cs = append(cs, c)
		}
	} else {
		for _, arg := range args {
			c := b.CommitByRev("reword", arg)
			cs = append(cs, c)
		}
	}
	for _, c := range cs {
		newMsg[c] = ""
	}

	// Invoke editor to reword all the messages message.
	// Save the edits to REWORD_MSGS immediately after editor exit
	// in case we for some reason cannot apply the changes - don't want
	// to throw away the user's writing.
	// But we don't use REWORD_MSGS as the actual editor file,
	// because if there are multiple git rewords happening
	// (perhaps the user has forgotten about one in another window),
	// we don't want them to step on each other during editing.
	var buf bytes.Buffer
	saveFile := filepath.Join(gitPathDir(), "REWORD_MSGS")
	saveBuf := func() {
		if err := os.WriteFile(saveFile, buf.Bytes(), 0666); err != nil {
			dief("cannot save messages: %v", err)
		}
	}
	saveBuf() // make sure it works before we let the user edit anything
	printf("editing messages (new texts logged in %s in case of failure)", saveFile)
	note := "edited messages saved in " + saveFile

	if len(cs) == 1 {
		c := cs[0]
		edited := editor(c.Message)
		if edited == "" {
			dief("edited message is empty")
		}
		newMsg[c] = string(fixCommitMessage([]byte(edited)))
		fmt.Fprintf(&buf, "# %s\n\n%s\n\n", c.Subject, edited)
		saveBuf()
	} else {
		// Edit all at once.
		var ed bytes.Buffer
		ed.WriteString(rewordProlog)
		byHash := make(map[string]*Commit)
		for _, c := range cs {
			if strings.HasPrefix(c.Message, "# ") || strings.Contains(c.Message, "\n# ") {
				// Will break our framing.
				// Should be pretty rare since 'git commit' and 'git commit --amend'
				// delete lines beginning with # after editing sessions.
				dief("commit %.7s has a message line beginning with # - cannot reword with other commits", c.Hash)
			}
			hash := c.Hash[:7]
			byHash[hash] = c
			// Two blank lines before #, one after.
			// Lots of space to make it easier to see the boundaries
			// between commit messages.
			fmt.Fprintf(&ed, "\n\n# %s %s\n\n%s\n", hash, c.Subject, c.Message)
		}
		edited := editor(ed.String())
		if edited == "" {
			dief("edited text is empty")
		}

		// Save buffer for user before going further.
		buf.WriteString(edited)
		saveBuf()

		for i, text := range strings.Split("\n"+edited, "\n# ") {
			if i == 0 {
				continue
			}
			text = "# " + text // restore split separator

			// Pull out # hash header line and body.
			hdr, body, _ := strings.Cut(text, "\n")

			// Cut blank lines at start and end of body but keep newline-terminated.
			for body != "" {
				line, rest, _ := strings.Cut(body, "\n")
				if line != "" {
					break
				}
				body = rest
			}
			body = strings.TrimRight(body, " \t\n")
			if body != "" {
				body += "\n"
			}

			// Look up hash.
			f := strings.Fields(hdr)
			if len(f) < 2 {
				dief("edited text has # line with no commit hash\n%s", note)
			}
			c := byHash[f[1]]
			if c == nil {
				dief("cannot find commit for header: %s\n%s", strings.TrimSpace(hdr), note)
			}
			newMsg[c] = string(fixCommitMessage([]byte(body)))
		}
	}

	// Rebuild the commits the way git would,
	// but without doing any git checkout that
	// would affect the files in the working directory.
	var newHash string
	last = nil
	for i := len(pending) - 1; i >= 0; i-- {
		c := pending[i]
		if (newMsg[c] == "" || newMsg[c] == c.Message) && newHash == "" {
			// Have not started making changes yet. Leave exactly as is.
			last = c
			continue
		}
		// Rebuilding.
		msg := newMsg[c]
		if msg == "" {
			msg = c.Message
		}
		if last != nil && newHash != "" && !c.HasParent(last.Hash) {
			dief("internal error: confused about pending commit graph")
		}
		gitArgs := []string{"commit-tree", "-p"}
		for _, p := range c.Parents {
			if last != nil && newHash != "" && p == last.Hash {
				p = newHash
			}
			gitArgs = append(gitArgs, p)
		}
		gitArgs = append(gitArgs, "-m", msg, c.Tree)
		os.Setenv("GIT_AUTHOR_NAME", c.AuthorName)
		os.Setenv("GIT_AUTHOR_EMAIL", c.AuthorEmail)
		os.Setenv("GIT_AUTHOR_DATE", c.AuthorDate)
		newHash = trim(cmdOutput("git", gitArgs...))
		last = c
	}
	if newHash == "" {
		// No messages changed.
		return
	}

	// Attempt swap of HEAD but leave index and working copy alone.
	// No obvious way to make it atomic, but check for races.
	head, branch = headState()
	if head != pending[0].Hash {
		dief("cannot reword: commits changed underfoot\n%s", note)
	}
	if branch != b.Name {
		dief("cannot reword: branch changed underfoot\n%s", note)
	}
	run("git", "reset", "--soft", newHash)
}

var rewordProlog = `Rewording multiple commit messages.
The # lines separate the different commits and must be left unchanged.
`
