// Copyright 2017 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 godata

import (
	"context"
	"sync"
	"testing"

	"golang.org/x/build/maintner"
)

func BenchmarkGet(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		_, err := Get(context.Background())
		if err != nil {
			b.Fatal(err)
		}
	}
}

var (
	corpusMu    sync.Mutex
	corpusCache *maintner.Corpus
)

func getGoData(tb testing.TB) *maintner.Corpus {
	if testing.Short() {
		tb.Skip("not running tests requiring large download in short mode")
	}
	corpusMu.Lock()
	defer corpusMu.Unlock()
	if corpusCache != nil {
		return corpusCache
	}
	var err error
	corpusCache, err = Get(context.Background())
	if err != nil {
		tb.Fatalf("getting corpus: %v", err)
	}
	return corpusCache
}

func TestCorpusCheck(t *testing.T) {
	c := getGoData(t)
	if err := c.Check(); err != nil {
		t.Fatal(err)
	}
}

func TestGerritForeachNonChangeRef(t *testing.T) {
	c := getGoData(t)
	c.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		t.Logf("%s:", gp.ServerSlashProject())
		gp.ForeachNonChangeRef(func(ref string, hash maintner.GitHash) error {
			t.Logf("  %s %s", hash, ref)
			return nil
		})
		return nil
	})
}

// In the past, some Gerrit ref changes came before the git in the log.
// This tests that we handle Gerrit meta changes that happen before
// the referenced git commit is known.
func TestGerritOutOfOrderMetaChanges(t *testing.T) {
	c := getGoData(t)

	// Merged:
	goProj := c.Gerrit().Project("go.googlesource.com", "go")
	cl := goProj.CL(38634)
	if cl == nil {
		t.Fatal("CL 38634 not found")
	}
	if g, w := cl.Status, "merged"; g != w {
		t.Errorf("CL status = %q; want %q", g, w)
	}

	// Deleted:
	gddo := c.Gerrit().Project("go.googlesource.com", "gddo")
	cl = gddo.CL(37452)
	if cl == nil {
		t.Fatal("CL 37452 not found")
	}
	t.Logf("Got: %+v", *cl)
}

func TestGerritSkipPrivateCLs(t *testing.T) {
	c := getGoData(t)
	proj := c.Gerrit().Project("go.googlesource.com", "gddo")
	proj.ForeachOpenCL(func(cl *maintner.GerritCL) error {
		if cl.Number == 37452 {
			t.Error("unexpected private CL 37452")
		}
		return nil
	})
}

func TestGitAncestor(t *testing.T) {
	c := getGoData(t)
	tests := []struct {
		subject, ancestor string
		want              bool
	}{
		{"3b5637ff2bd5c03479780995e7a35c48222157c1", "0bb0b61d6a85b2a1a33dcbc418089656f2754d32", true},
		{"0bb0b61d6a85b2a1a33dcbc418089656f2754d32", "3b5637ff2bd5c03479780995e7a35c48222157c1", false},

		{"8f06e217eac10bae4993ca371ade35fecd26270e", "22f1b56dab29d397d2bdbdd603d85e60fb678089", true},
		{"22f1b56dab29d397d2bdbdd603d85e60fb678089", "8f06e217eac10bae4993ca371ade35fecd26270e", false},

		// Was crashing. Issue 22753.
		{"3a181dc7bc8fd0c61d6090a85f87c934f1874802", "f65abf6ddc8d1f3d403a9195fd74eaffa022b07f", true},
		// The reverse of the above, to try to reproduce the
		// panic if I got the order backwards:
		{"f65abf6ddc8d1f3d403a9195fd74eaffa022b07f", "3a181dc7bc8fd0c61d6090a85f87c934f1874802", false},

		// Same on both sides:
		{"0bb0b61d6a85b2a1a33dcbc418089656f2754d32", "0bb0b61d6a85b2a1a33dcbc418089656f2754d32", false},
		{"3b5637ff2bd5c03479780995e7a35c48222157c1", "3b5637ff2bd5c03479780995e7a35c48222157c1", false},
	}
	for i, tt := range tests {
		subject := c.GitCommit(tt.subject)
		if subject == nil {
			t.Errorf("%d. missing subject commit %q", i, tt.subject)
			continue
		}
		anc := c.GitCommit(tt.ancestor)
		if anc == nil {
			t.Errorf("%d. missing ancestor commit %q", i, tt.ancestor)
			continue
		}
		got := subject.HasAncestor(anc)
		if got != tt.want {
			t.Errorf("HasAncestor(%q, %q) = %v; want %v", tt.subject, tt.ancestor, got, tt.want)
		}
	}
}

func BenchmarkGitAncestor(b *testing.B) {
	c := getGoData(b)
	subject := c.GitCommit("3b5637ff2bd5c03479780995e7a35c48222157c1")
	anc := c.GitCommit("0bb0b61d6a85b2a1a33dcbc418089656f2754d32")
	if subject == nil || anc == nil {
		b.Fatal("missing commit(s)")
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if !subject.HasAncestor(anc) {
			b.Fatal("wrong answer")
		}
	}
}

// Issue 23007: a Gerrit CL can switch branches. Make sure we handle that.
func TestGerritCLChangingBranches(t *testing.T) {
	c := getGoData(t)

	tests := []struct {
		server, project string
		cl              int32
		want            string
	}{
		// Changed branch in the middle:
		// (Unsubmitted at the time of this test, so if it changes back, this test
		// may break.)
		{"go.googlesource.com", "go", 33776, "master"},

		// Submitted to boringcrypto:
		{"go.googlesource.com", "go", 82138, "dev.boringcrypto"},
		// Submitted to master:
		{"go.googlesource.com", "go", 83578, "master"},
	}

	for _, tt := range tests {
		cl := c.Gerrit().Project(tt.server, tt.project).CL(tt.cl)
		if got := cl.Branch(); got != tt.want {
			t.Errorf("%q, %q, CL %d = branch %q; want %q", tt.server, tt.project, tt.cl, got, tt.want)
		}
	}
}
