// Copyright 2017 The Fuchsia 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 (
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"testing"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/gitutil"
	"go.fuchsia.dev/jiri/jiritest"
	"go.fuchsia.dev/jiri/project"
)

func setDefaultStatusFlags() {
	statusFlags.changes = true
	statusFlags.checkHead = true
	statusFlags.branch = ""
	statusFlags.commits = true
	statusFlags.deleted = false
}

func createCommits(t *testing.T, fake *jiritest.FakeJiriRoot, localProjects []project.Project) ([]string, []string, []string, []string) {
	cwd, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}
	var file2CommitRevs []string
	var file1CommitRevs []string
	var latestCommitRevs []string
	var relativePaths []string
	for i, localProject := range localProjects {
		setDummyUser(t, fake.X, fake.Projects[localProject.Name])
		gitRemote := gitutil.New(fake.X, gitutil.RootDirOpt(fake.Projects[localProject.Name]))
		writeFile(t, fake.X, fake.Projects[localProject.Name], "file1"+strconv.Itoa(i), "file1"+strconv.Itoa(i))
		gitRemote.CreateAndCheckoutBranch("file-1")
		gitRemote.CheckoutBranch("main", localProject.GitSubmodules, false)
		file1CommitRev, _ := gitRemote.CurrentRevision()
		file1CommitRevs = append(file1CommitRevs, file1CommitRev)
		gitRemote.CreateAndCheckoutBranch("file-2")
		gitRemote.CheckoutBranch("main", localProject.GitSubmodules, false)
		writeFile(t, fake.X, fake.Projects[localProject.Name], "file2"+strconv.Itoa(i), "file2"+strconv.Itoa(i))
		file2CommitRev, _ := gitRemote.CurrentRevision()
		file2CommitRevs = append(file2CommitRevs, file2CommitRev)
		writeFile(t, fake.X, fake.Projects[localProject.Name], "file3"+strconv.Itoa(i), "file3"+strconv.Itoa(i))
		file3CommitRev, _ := gitRemote.CurrentRevision()
		latestCommitRevs = append(latestCommitRevs, file3CommitRev)
		relativePath, _ := filepath.Rel(cwd, localProject.Path)
		relativePaths = append(relativePaths, relativePath)
	}
	return file1CommitRevs, file2CommitRevs, latestCommitRevs, relativePaths
}

func createProjects(t *testing.T, fake *jiritest.FakeJiriRoot, numProjects int) []project.Project {
	localProjects := []project.Project{}
	for i := 0; i < numProjects; i++ {
		name := fmt.Sprintf("project-%d", i)
		path := fmt.Sprintf("path-%d", i)
		if err := fake.CreateRemoteProject(name); err != nil {
			t.Fatal(err)
		}
		p := project.Project{
			Name:   name,
			Path:   filepath.Join(fake.X.Root, path),
			Remote: fake.Projects[name],
		}
		localProjects = append(localProjects, p)
		if err := fake.AddProject(p); err != nil {
			t.Fatal(err)
		}
	}
	return localProjects
}

func expectedOutput(t *testing.T, fake *jiritest.FakeJiriRoot, localProjects []project.Project,
	latestCommitRevs, currentCommits, changes, currentBranch, relativePaths []string, extraCommitLogs [][]string) string {
	want := ""
	for i, localProject := range localProjects {
		includeForNotHead := statusFlags.checkHead && currentCommits[i] != latestCommitRevs[i]
		includeForChanges := statusFlags.changes && changes[i] != ""
		includeForCommits := statusFlags.commits && extraCommitLogs != nil && len(extraCommitLogs[i]) != 0
		includeProject := (statusFlags.branch == "" && (includeForNotHead || includeForChanges || includeForCommits)) ||
			(statusFlags.branch != "" && statusFlags.branch == currentBranch[i])
		if includeProject {
			gitLocal := gitutil.New(fake.X, gitutil.RootDirOpt(localProject.Path))
			currentLog, err := gitLocal.OneLineLog(currentCommits[i])
			if err != nil {
				t.Error(err)
			}
			want = fmt.Sprintf("%s%s: ", want, relativePaths[i])
			if currentCommits[i] != latestCommitRevs[i] && statusFlags.checkHead {
				log, err := gitLocal.OneLineLog(latestCommitRevs[i])
				if err != nil {
					t.Error(err)
				}
				want = fmt.Sprintf("%s\nJIRI_HEAD: %s", want, log)
				want = fmt.Sprintf("%s\nCurrent Revision: %s", want, currentLog)
			}
			want = fmt.Sprintf("%s\nBranch: ", want)
			branchmsg := currentBranch[i]
			if branchmsg == "" {
				branchmsg = fmt.Sprintf("DETACHED-HEAD(%s)", currentLog)
			}
			want = fmt.Sprintf("%s%s", want, branchmsg)
			if extraCommitLogs != nil && statusFlags.commits && len(extraCommitLogs[i]) != 0 {
				want = fmt.Sprintf("%s\nCommits: %d commit(s) not merged to remote", want, len(extraCommitLogs[i]))
				for _, commitLog := range extraCommitLogs[i] {
					want = fmt.Sprintf("%s\n%s", want, commitLog)
				}

			}
			if statusFlags.changes && changes[i] != "" {
				want = fmt.Sprintf("%s\n%s", want, changes[i])
			}
			want = fmt.Sprintf("%s\n\n", want)
		}
	}
	want = strings.TrimSpace(want)
	return want
}

func TestStatus(t *testing.T) {
	setDefaultStatusFlags()
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()

	// Add projects
	numProjects := 3
	localProjects := createProjects(t, fake, numProjects)
	file1CommitRevs, file2CommitRevs, latestCommitRevs, relativePaths := createCommits(t, fake, localProjects)
	if err := fake.UpdateUniverse(false); err != nil {
		t.Fatal(err)
	}

	for _, lp := range localProjects {
		setDummyUser(t, fake.X, lp.Path)
	}
	// Test no changes
	got := executeStatus(t, fake, "")
	want := ""
	if got != want {
		t.Errorf("got %s, want %s", got, want)
	}

	// Test when HEAD is on different revsion
	gitLocal := gitutil.New(fake.X, gitutil.RootDirOpt(localProjects[1].Path))
	gitLocal.CheckoutBranch("HEAD~1", localProjects[1].GitSubmodules, false)
	gitLocal = gitutil.New(fake.X, gitutil.RootDirOpt(localProjects[2].Path))
	gitLocal.CheckoutBranch("file-2", localProjects[2].GitSubmodules, false)
	got = executeStatus(t, fake, "")
	currentCommits := []string{latestCommitRevs[0], file2CommitRevs[1], file1CommitRevs[2]}
	currentBranch := []string{"", "", "file-2"}
	changes := []string{"", "", ""}
	want = expectedOutput(t, fake, localProjects, latestCommitRevs, currentCommits, changes, currentBranch, relativePaths, nil)
	if !equal(got, want) {
		t.Errorf("got %s, want %s", got, want)
	}

	// Test combinations of tracked and untracked changes
	newfile(t, localProjects[0].Path, "untracked1")
	newfile(t, localProjects[0].Path, "untracked2")
	newfile(t, localProjects[2].Path, "uncommitted.go")
	if err := gitLocal.Add("uncommitted.go"); err != nil {
		t.Error(err)
	}
	got = executeStatus(t, fake, "")
	currentCommits = []string{latestCommitRevs[0], file2CommitRevs[1], file1CommitRevs[2]}
	currentBranch = []string{"", "", "file-2"}
	changes = []string{"?? untracked1\n?? untracked2", "", "A  uncommitted.go"}
	want = expectedOutput(t, fake, localProjects, latestCommitRevs, currentCommits, changes, currentBranch, relativePaths, nil)
	if !equal(got, want) {
		t.Errorf("got %s, want %s", got, want)
	}
}

func TestStatusWhenUserUpdatesGitTree(t *testing.T) {
	setDefaultStatusFlags()
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()

	// Add projects
	numProjects := 1
	localProjects := createProjects(t, fake, numProjects)
	if err := fake.UpdateUniverse(false); err != nil {
		t.Fatal(err)
	}

	// write to remote
	writeFile(t, fake.X, fake.Projects[localProjects[0].Name], "file", "file")
	// git fetch
	gitLocal := gitutil.New(fake.X, gitutil.RootDirOpt(localProjects[0].Path))
	if err := gitLocal.Fetch("origin", false); err != nil {
		t.Fatal(err)
	}

	got := executeStatus(t, fake, "")
	want := "" // no change
	if got != want {
		t.Errorf("got %s, want %s", got, want)
	}
}

func TestStatusDeleted(t *testing.T) {
	setDefaultStatusFlags()
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()

	// Add projects
	numProjects := 5
	createProjects(t, fake, numProjects)
	if err := fake.UpdateUniverse(false); err != nil {
		t.Fatal(err)
	}

	// delete some projects
	manifest, err := fake.ReadRemoteManifest()
	if err != nil {
		t.Fatal(err)
	}
	deletedProjs := manifest.Projects[3:]
	manifest.Projects = manifest.Projects[0:3]
	if err := fake.WriteRemoteManifest(manifest); err != nil {
		t.Fatal(err)
	}
	if err := fake.UpdateUniverse(false); err != nil {
		t.Fatal(err)
	}

	statusFlags.deleted = true

	got := executeStatus(t, fake, "")
	numOfLines := len(strings.Split(got, "\n"))
	if numOfLines != 3 {
		t.Errorf("got %s, wanted 3 deleted projects", got)
	}
	for _, dp := range deletedProjs {
		if !strings.Contains(got, dp.Name) {
			t.Fatalf("project %s should have been deleted, got\n%s", dp.Name, got)
		}
		if !strings.Contains(got, dp.Path) {
			t.Fatalf("project %s should have been deleted, got\n%s", dp.Path, got)
		}
	}
}

func statusFlagsTest(t *testing.T) {
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()

	// Add projects
	numProjects := 6
	localProjects := createProjects(t, fake, numProjects)
	file1CommitRevs, file2CommitRevs, latestCommitRevs, relativePaths := createCommits(t, fake, localProjects)
	if err := fake.UpdateUniverse(false); err != nil {
		t.Fatal(err)
	}
	gitLocals := make([]*gitutil.Git, numProjects)
	for i, localProject := range localProjects {
		gitLocal := gitutil.New(fake.X, gitutil.UserNameOpt("John Doe"), gitutil.UserEmailOpt("john.doe@example.com"), gitutil.RootDirOpt(localProject.Path))
		gitLocals[i] = gitLocal
	}

	gitLocals[0].CheckoutBranch("HEAD~1", localProjects[0].GitSubmodules, false)
	gitLocals[1].CheckoutBranch("file-2", localProjects[1].GitSubmodules, false)
	gitLocals[3].CheckoutBranch("HEAD~2", localProjects[3].GitSubmodules, false)
	gitLocals[4].CheckoutBranch("main", localProjects[4].GitSubmodules, false)
	gitLocals[5].CheckoutBranch("main", localProjects[5].GitSubmodules, false)

	newfile(t, localProjects[0].Path, "untracked1")
	newfile(t, localProjects[0].Path, "untracked2")

	newfile(t, localProjects[1].Path, "uncommitted.go")
	if err := gitLocals[1].Add("uncommitted.go"); err != nil {
		t.Error(err)
	}

	newfile(t, localProjects[2].Path, "untracked1")
	newfile(t, localProjects[2].Path, "uncommitted.go")
	if err := gitLocals[2].Add("uncommitted.go"); err != nil {
		t.Error(err)
	}

	extraCommits5 := []string{}
	for i := 0; i < 2; i++ {
		file := fmt.Sprintf("extrafile%d", i)
		writeFile(t, fake.X, localProjects[5].Path, file, file+"log")
		log, err := gitLocals[5].OneLineLog("HEAD")
		if err != nil {
			t.Error(err)
		}
		extraCommits5 = append([]string{log}, extraCommits5...)
	}
	gl5 := gitutil.New(fake.X, gitutil.RootDirOpt(localProjects[5].Path))
	currentCommit5, err := gl5.CurrentRevision()
	if err != nil {
		t.Error(err)
	}
	got := executeStatus(t, fake, "")
	currentCommits := []string{file2CommitRevs[0], file1CommitRevs[1], latestCommitRevs[2], file1CommitRevs[3], latestCommitRevs[4], currentCommit5}
	extraCommitLogs := [][]string{nil, nil, nil, nil, nil, extraCommits5}
	currentBranch := []string{"", "file-2", "", "", "main", "main"}
	changes := []string{"?? untracked1\n?? untracked2", "A  uncommitted.go", "A  uncommitted.go\n?? untracked1", "", "", ""}
	want := expectedOutput(t, fake, localProjects, latestCommitRevs, currentCommits, changes, currentBranch, relativePaths, extraCommitLogs)
	if !equal(got, want) {
		printStatusFlags()
		t.Errorf("got %s, want %s", got, want)
	}
}

func printStatusFlags() {
	fmt.Printf("changes=%t, check-head=%t, commits=%t\n", statusFlags.changes, statusFlags.checkHead, statusFlags.commits)
}

func TestStatusFlags(t *testing.T) {
	setDefaultStatusFlags()
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.changes = false
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.changes = false
	statusFlags.checkHead = false
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.checkHead = false
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.changes = false
	statusFlags.checkHead = false
	statusFlags.branch = "main"
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.checkHead = false
	statusFlags.branch = "main"
	statusFlags.commits = false
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.changes = false
	statusFlags.branch = "main"
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.changes = false
	statusFlags.checkHead = false
	statusFlags.branch = "file-2"
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.checkHead = false
	statusFlags.branch = "file-2"
	statusFlagsTest(t)

	setDefaultStatusFlags()
	statusFlags.changes = false
	statusFlags.branch = "file-2"
	statusFlagsTest(t)
}

func equal(first, second string) bool {
	firstStrings := strings.Split(first, "\n\n")
	secondStrings := strings.Split(second, "\n\n")
	if len(firstStrings) != len(secondStrings) {
		return false
	}
	sort.Strings(firstStrings)
	sort.Strings(secondStrings)
	for i, first := range firstStrings {
		if first != secondStrings[i] {
			return false
		}
	}
	return true
}

func executeStatus(t *testing.T, fake *jiritest.FakeJiriRoot, args ...string) string {
	stderr := ""
	runCmd := func() {
		if err := runStatus(fake.X, args); err != nil {
			stderr = err.Error()
		}
	}
	stdout, _, err := runfunc(runCmd)
	if err != nil {
		t.Fatal(err)
	}
	return strings.TrimSpace(strings.Join([]string{stdout, stderr}, " "))
}

func writeFile(t *testing.T, jirix *jiri.X, projectDir, fileName, message string) {
	path, perm := filepath.Join(projectDir, fileName), os.FileMode(0644)
	if err := os.WriteFile(path, []byte(message), perm); err != nil {
		t.Fatalf("WriteFile(%s, %d) failed: %s", path, perm, err)
	}
	if err := gitutil.New(jirix, gitutil.RootDirOpt(projectDir),
		gitutil.UserNameOpt("John Doe"),
		gitutil.UserEmailOpt("john.doe@example.com")).CommitFile(path,
		message); err != nil {
		t.Fatal(err)
	}
}

func setDummyUser(t *testing.T, jirix *jiri.X, projectDir string) {
	git := gitutil.New(jirix, gitutil.RootDirOpt(projectDir))
	if err := git.Config("user.email", "john.doe@example.com"); err != nil {
		t.Fatal(err)
	}
	if err := git.Config("user.name", "John Doe"); err != nil {
		t.Fatal(err)
	}
}

func newfile(t *testing.T, dir, file string) {
	testfile := filepath.Join(dir, file)
	_, err := os.Create(testfile)
	if err != nil {
		t.Errorf("failed to create %s: %s", testfile, err)
	}
}
