// Copyright 2014 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 (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"testing"
)

const (
	goodGo      = "package good\n"
	badGo       = " package bad1 "
	badGoFixed  = "package bad1\n"
	bad2Go      = " package bad2 "
	bad2GoFixed = "package bad2\n"
	brokenGo    = "package B R O K E N"
)

func TestGofmt(t *testing.T) {
	// Test of basic operations.
	gt := newGitTest(t)
	defer gt.done()

	gt.work(t)

	if err := os.MkdirAll(gt.client+"/test/bench", 0755); err != nil {
		t.Fatal(err)
	}
	if err := os.MkdirAll(gt.client+"/vendor", 0755); err != nil {
		t.Fatal(err)
	}
	write(t, gt.client+"/bad.go", badGo, 0644)
	write(t, gt.client+"/good.go", goodGo, 0644)
	write(t, gt.client+"/vendor/bad.go", badGo, 0644)
	write(t, gt.client+"/test/bad.go", badGo, 0644)
	write(t, gt.client+"/test/good.go", goodGo, 0644)
	write(t, gt.client+"/test/bench/bad.go", badGo, 0644)
	write(t, gt.client+"/test/bench/good.go", goodGo, 0644)
	trun(t, gt.client, "git", "add", ".") // make files tracked

	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, "bad.go\n", "!good.go", fromSlash("!test/bad"), fromSlash("test/bench/bad.go"), fromSlash("!vendor/bad.go"))
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, "bad.go\n", "!good.go", fromSlash("!test/bad"), fromSlash("test/bench/bad.go"), fromSlash("!vendor/bad.go"))

	testMain(t, "gofmt")
	testNoStdout(t)

	testMain(t, "gofmt", "-l")
	testNoStdout(t)

	write(t, gt.client+"/bad.go", badGo, 0644)
	write(t, gt.client+"/broken.go", brokenGo, 0644)
	trun(t, gt.client, "git", "add", ".")
	testMainDied(t, "gofmt", "-l")
	testPrintedStdout(t, "bad.go")
	testPrintedStderr(t, "gofmt reported errors", "broken.go")
}

func TestGofmtSubdir(t *testing.T) {
	// Check that gofmt prints relative paths for files in or below the current directory.
	gt := newGitTest(t)
	defer gt.done()

	gt.work(t)

	mkdir(t, gt.client+"/dir1")
	mkdir(t, gt.client+"/longnamedir2")
	write(t, gt.client+"/dir1/bad1.go", badGo, 0644)
	write(t, gt.client+"/longnamedir2/bad2.go", badGo, 0644)
	trun(t, gt.client, "git", "add", ".") // make files tracked

	chdir(t, gt.client)
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, fromSlash("dir1/bad1.go"), fromSlash("longnamedir2/bad2.go"))

	chdir(t, gt.client+"/dir1")
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, "bad1.go", fromSlash("!/bad1.go"), fromSlash("longnamedir2/bad2.go"))

	chdir(t, gt.client+"/longnamedir2")
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, "bad2.go", fromSlash("!/bad2.go"), fromSlash("dir1/bad1.go"))

	mkdir(t, gt.client+"/z")
	chdir(t, gt.client+"/z")
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, fromSlash("longnamedir2/bad2.go"), fromSlash("dir1/bad1.go"))
}

func TestGofmtSubdirIndexCheckout(t *testing.T) {
	// Like TestGofmtSubdir but bad Go files are only in index, not working copy.
	// Check also that prints a correct path (relative or absolute) for files outside the
	// current directory, even when running with Git before 2.3.0 which doesn't
	// handle those right in git checkout-index --temp.

	gt := newGitTest(t)
	defer gt.done()

	gt.work(t)

	mkdir(t, gt.client+"/dir1")
	mkdir(t, gt.client+"/longnamedir2")
	write(t, gt.client+"/dir1/bad1.go", badGo, 0644)
	write(t, gt.client+"/longnamedir2/bad2.go", badGo, 0644)
	trun(t, gt.client, "git", "add", ".") // put files in index
	write(t, gt.client+"/dir1/bad1.go", goodGo, 0644)
	write(t, gt.client+"/longnamedir2/bad2.go", goodGo, 0644)

	chdir(t, gt.client)
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, fromSlash("dir1/bad1.go (staged)"), fromSlash("longnamedir2/bad2.go (staged)"))

	chdir(t, gt.client+"/dir1")
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, "bad1.go (staged)", fromSlash("!/bad1.go"), fromSlash("longnamedir2/bad2.go (staged)"))

	chdir(t, gt.client+"/longnamedir2")
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, "bad2.go (staged)", fromSlash("!/bad2.go"), fromSlash("dir1/bad1.go (staged)"))

	mkdir(t, gt.client+"/z")
	chdir(t, gt.client+"/z")
	testMain(t, "gofmt", "-l")
	testPrintedStdout(t, fromSlash("longnamedir2/bad2.go (staged)"), fromSlash("dir1/bad1.go (staged)"))
}

func TestGofmtUnstaged(t *testing.T) {
	// Test when unstaged files are different from staged ones.
	// See TestHookPreCommitUnstaged for an explanation.
	// In this test we use two different kinds of bad files, so that
	// we can test having a bad file in the index and a different
	// bad file in the working directory.

	gt := newGitTest(t)
	defer gt.done()
	gt.work(t)

	name := []string{"good", "bad", "bad2", "broken"}
	orig := []string{goodGo, badGo, bad2Go, brokenGo}
	fixed := []string{goodGo, badGoFixed, bad2GoFixed, brokenGo}
	const N = 4

	var allFiles, wantOut, wantErr []string
	writeFiles := func(n int) {
		allFiles = nil
		wantOut = nil
		wantErr = nil
		for i := 0; i < N*N*N; i++ {
			// determine n'th digit of 3-digit base-N value i
			j := i
			for k := 0; k < (3 - 1 - n); k++ {
				j /= N
			}
			text := orig[j%N]
			file := fmt.Sprintf("%s-%s-%s.go", name[i/N/N], name[(i/N)%N], name[i%N])
			allFiles = append(allFiles, file)
			write(t, gt.client+"/"+file, text, 0644)

			if (i/N)%N != i%N {
				staged := file + " (staged)"
				switch {
				case strings.Contains(file, "-bad-"), strings.Contains(file, "-bad2-"):
					wantOut = append(wantOut, staged)
					wantErr = append(wantErr, "!"+staged)
				case strings.Contains(file, "-broken-"):
					wantOut = append(wantOut, "!"+staged)
					wantErr = append(wantErr, staged)
				default:
					wantOut = append(wantOut, "!"+staged)
					wantErr = append(wantErr, "!"+staged)
				}
			}
			switch {
			case strings.Contains(file, "-bad.go"), strings.Contains(file, "-bad2.go"):
				if (i/N)%N != i%N {
					file += " (unstaged)"
				}
				wantOut = append(wantOut, file+"\n")
				wantErr = append(wantErr, "!"+file+":", "!"+file+" (unstaged)")
			case strings.Contains(file, "-broken.go"):
				wantOut = append(wantOut, "!"+file+"\n", "!"+file+" (unstaged)")
				wantErr = append(wantErr, file+":")
			default:
				wantOut = append(wantOut, "!"+file+"\n", "!"+file+":", "!"+file+" (unstaged)")
				wantErr = append(wantErr, "!"+file+"\n", "!"+file+":", "!"+file+" (unstaged)")
			}
		}
	}

	// committed files
	writeFiles(0)
	trun(t, gt.client, "git", "add", ".")
	trun(t, gt.client, "git", "commit", "-m", "msg")

	// staged files
	writeFiles(1)
	trun(t, gt.client, "git", "add", ".")

	// unstaged files
	writeFiles(2)

	// Check that gofmt -l shows the right output and errors.
	testMainDied(t, "gofmt", "-l")
	testPrintedStdout(t, wantOut...)
	testPrintedStderr(t, wantErr...)

	// Again (last command should not have written anything).
	testMainDied(t, "gofmt", "-l")
	testPrintedStdout(t, wantOut...)
	testPrintedStderr(t, wantErr...)

	// Reformat in place.
	testMainDied(t, "gofmt")
	testNoStdout(t)
	testPrintedStderr(t, wantErr...)

	// Read files to make sure unstaged did not bleed into staged.
	for i, file := range allFiles {
		if data, err := ioutil.ReadFile(gt.client + "/" + file); err != nil {
			t.Errorf("%v", err)
		} else if want := fixed[i%N]; string(data) != want {
			t.Errorf("%s: working tree = %q, want %q", file, string(data), want)
		}
		if data, want := trun(t, gt.client, "git", "show", ":"+file), fixed[i/N%N]; data != want {
			t.Errorf("%s: index = %q, want %q", file, data, want)
		}
		if data, want := trun(t, gt.client, "git", "show", "HEAD:"+file), orig[i/N/N]; data != want {
			t.Errorf("%s: commit = %q, want %q", file, data, want)
		}
	}

	// Check that gofmt -l still shows the errors.
	testMainDied(t, "gofmt", "-l")
	testNoStdout(t)
	testPrintedStderr(t, wantErr...)
}

func TestGofmtAmbiguousRevision(t *testing.T) {
	gt := newGitTest(t)
	defer gt.done()

	t.Logf("creating file that conflicts with revision parameter")
	write(t, gt.client+"/HEAD", "foo", 0644)

	testMain(t, "gofmt")
}

func TestGofmtFastForwardMerge(t *testing.T) {
	gt := newGitTest(t)
	defer gt.done()

	// merge dev.branch into main
	write(t, gt.server+"/file", "more work", 0644)
	trun(t, gt.server, "git", "commit", "-m", "work", "file")
	trun(t, gt.server, "git", "merge", "-m", "merge", "dev.branch")

	// add bad go file on main
	write(t, gt.server+"/bad.go", "package {\n", 0644)
	trun(t, gt.server, "git", "add", "bad.go")
	trun(t, gt.server, "git", "commit", "-m", "bad go")

	// update client
	trun(t, gt.client, "git", "checkout", "main")
	trun(t, gt.client, "git", "pull")
	testMain(t, "change", "dev.branch")
	trun(t, gt.client, "git", "pull")

	// merge main into dev.branch, fast forward merge
	trun(t, gt.client, "git", "merge", "--ff-only", "main")

	// verify that now client is in a state where just the tag is changing; there's no new commit.
	mainHash := strings.TrimSpace(trun(t, gt.server, "git", "rev-parse", "main"))
	devHash := strings.TrimSpace(trun(t, gt.client, "git", "rev-parse", "HEAD"))

	if mainHash != devHash {
		t.Logf("branches:\n%s", trun(t, gt.client, "git", "branch", "-a", "-v"))
		t.Logf("log:\n%s", trun(t, gt.client, "git", "log", "--graph", "--decorate"))
		t.Fatalf("setup wrong - got different commit hashes on main and dev branch")
	}

	// check that gofmt finds nothing to do, ignoring the bad (but committed) file1.go.
	testMain(t, "gofmt")
	testNoStdout(t)
	testNoStderr(t)
}
