/*
   Package mem_git provides convenience functionality for writing test data into a GitStore.
*/

package mem_git

import (
	"context"
	"crypto/sha1"
	"fmt"
	"time"

	"github.com/stretchr/testify/require"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/git/git_common"
	"go.skia.org/infra/go/gitstore"
	"go.skia.org/infra/go/sktest"
	"go.skia.org/infra/go/testutils"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/go/vcsinfo"
)

const (
	// These are the commit hashes generated by CommitN(2) when run as the
	// first call to MemGit.
	Commit0 = "407108ae8039ba9dce77e81057721fc7c4dbab87"
	Commit1 = "a1dcf4a9669ff77919dfca71901ec98145b0af94"
)

var (
	// BaseTime is an arbitrary timestamp used as the time of the first
	// commit. Subsequent commits add a fixed duration to the timestamp
	// of their parent(s). This keeps the commit hashes predictable.
	BaseTime = time.Unix(1571926390, 0).UTC()
)

// FakeCommitAt creates a LongCommit with the given message at the given time,
// belonging to the given branch, and with the given parent commits. Its Index
// increases monotonically with respect to the parents.
func FakeCommitAt(t sktest.TestingT, msg, branch string, ts time.Time, parents ...*vcsinfo.LongCommit) *vcsinfo.LongCommit {
	index := 0
	var parentHashes []string
	if len(parents) > 0 {
		parentHashes = make([]string, 0, len(parents))
		for _, p := range parents {
			if p.Index >= index {
				index = p.Index + 1
			}
			parentHashes = append(parentHashes, p.Hash)
		}
	}
	lc := &vcsinfo.LongCommit{
		ShortCommit: &vcsinfo.ShortCommit{
			Author:  "me@google.com",
			Subject: msg,
		},
		Parents:   parentHashes,
		Timestamp: ts,
		Index:     index,
		Branches: map[string]bool{
			branch: true,
		},
	}
	j := testutils.MarshalJSON(t, lc)
	lc.Hash = fmt.Sprintf("%040x", sha1.Sum([]byte(j)))
	return lc
}

// FakeCommit creates a LongCommit with the given message, belonging to the
// given branch, and with the given parent commits. Its Timestamp and Index
// increase monotonically with respect to the parents.
func FakeCommit(t sktest.TestingT, msg, branch string, parents ...*vcsinfo.LongCommit) *vcsinfo.LongCommit {
	ts := BaseTime
	if len(parents) > 0 {
		for _, p := range parents {
			if !ts.After(p.Timestamp) {
				ts = p.Timestamp.Add(time.Minute)
			}
		}
	}
	return FakeCommitAt(t, msg, branch, ts, parents...)
}

// New returns a MemGit instance which writes to the given GitStore.
func New(t sktest.TestingT, gs gitstore.GitStore) *MemGit {
	return &MemGit{
		branch: git.MainBranch,
		gs:     gs,
		t:      t,
	}
}

// MemGit is a struct used for writing fake commits into a GitStore.
type MemGit struct {
	branch   string
	gs       gitstore.GitStore
	t        sktest.TestingT
	updaters []Updater
}

// head returns the current head of the given branch.
func (g *MemGit) head(branch string) string {
	branches, err := g.gs.GetBranches(context.Background())
	require.NoError(g.t, err)
	ptr, ok := branches[branch]
	if !ok {
		return ""
	}
	return ptr.Head
}

// makeCommit creates a commit with the given message and parents on the
// currently-active branch.
func (g *MemGit) makeCommit(msg string, ts time.Time, parentHashes []string) *vcsinfo.LongCommit {
	ctx := context.Background()
	parents := []*vcsinfo.LongCommit{}
	if len(parentHashes) > 0 {
		var err error
		parents, err = g.gs.Get(ctx, parentHashes)
		require.NoError(g.t, err)
		for _, p := range parents {
			require.NotNil(g.t, p)
		}
	}
	var lc *vcsinfo.LongCommit
	if util.TimeIsZero(ts) {
		lc = FakeCommit(g.t, msg, g.branch, parents...)
	} else {
		lc = FakeCommitAt(g.t, msg, g.branch, ts, parents...)
	}
	require.NoError(g.t, g.gs.Put(ctx, []*vcsinfo.LongCommit{lc}))
	require.NoError(g.t, g.gs.PutBranches(ctx, map[string]string{
		g.branch: lc.Hash,
	}))
	g.update()
	return lc
}

// Commit adds a commit to the GitStore with the given commit message and
// parents, and returns its hash.  If no parents are provided, the head of the
// current branch is used as the parent.  In either case, the head of the
// current branch is set to be the new commit.
func (g *MemGit) Commit(msg string, parents ...string) string {
	return g.CommitAt(msg, time.Time{}, parents...)
}

// CommitAt adds a commit to the GitStore with the given commit message,
// timestamp, and parents, and returns its hash. If no parents are provided,
// the head of the current branch is used as the parent.  In either case, the
// head of the current branch is set to be the new commit.
func (g *MemGit) CommitAt(msg string, ts time.Time, parents ...string) string {
	if len(parents) == 0 {
		head := g.head(g.branch)
		if head != "" {
			parents = []string{head}
		}
	}
	return g.makeCommit(msg, ts, parents).Hash
}

// CommitN adds N commits to the GitStore on the current branch and returns
// their hashes in reverse chronological order.
func (g *MemGit) CommitN(n int) []string {
	hashes := make([]string, 0, n)
	for i := 0; i < n; i++ {
		hashes = append(hashes, g.Commit(fmt.Sprintf("Fake #%d/%d", i, n)))
	}
	return util.Reverse(hashes)
}

// CheckoutBranch switches to the given branch.
func (g *MemGit) CheckoutBranch(branch string) {
	branches, err := g.gs.GetBranches(context.Background())
	require.NoError(g.t, err)
	ptr, ok := branches[branch]
	require.True(g.t, ok)
	require.NotNil(g.t, ptr)
	require.NotEqual(g.t, "", ptr.Head)
	g.branch = branch
}

// NewBranch creates the given branch at the given commit hash and switches to it.
func (g *MemGit) NewBranch(branch, head string) {
	ctx := context.Background()
	branches, err := g.gs.GetBranches(ctx)
	require.NoError(g.t, err)
	_, ok := branches[branch]
	require.False(g.t, ok, "Already have %s", branch)
	require.NoError(g.t, g.gs.PutBranches(ctx, map[string]string{
		branch: head,
	}))
	g.branch = branch
	g.update()
}

// Merge creates a new commit which merges the given branch into the currently
// active branch.
func (g *MemGit) Merge(branch string) string {
	return g.makeCommit(fmt.Sprintf("Merge %s", branch), time.Time{}, []string{g.head(g.branch), g.head(branch)}).Hash
}

// Updater is an interface used for automatically receiving updates when the
// MemGit changes.
type Updater interface {
	// Update indicates that the MemGit has changed. The Context passed to
	// Update is likely to be a placeholder or empty.
	Update(ctx context.Context) error
}

// AddUpdater adds the given Updater to the MemGit. Subsequent mutations to the
// MemGit will result in a call to Updater.Update().
func (g *MemGit) AddUpdater(u Updater) {
	g.updaters = append(g.updaters, u)
}

// update all of the registered Updaters.
func (g *MemGit) update() {
	for _, u := range g.updaters {
		require.NoError(g.t, u.Update(context.Background()))
	}
}

// FillWithBranchingHistory adds commits to the MemGit.
//
// The repo layout looks like this:
//
// older           newer
// c0--c1------c3--c4--
//       \-c2-----/
//
// Returns the commit hashes in order from c0-c4. This is analogous to
// git_builder.FillWithBranchingHistory.
func FillWithBranchingHistory(mg *MemGit) []string {
	c0 := mg.Commit("c0")
	c1 := mg.Commit("c1")
	mg.NewBranch("branch2", c1)
	c2 := mg.Commit("c2")
	mg.CheckoutBranch(git_common.MainBranch)
	c3 := mg.Commit("c3")
	c4 := mg.Merge("branch2")
	return []string{c0, c1, c2, c3, c4}
}
