// 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"
	"io/ioutil"
	"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 := ioutil.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.
`
