// Copyright 2019 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 sumdb

import (
	"bytes"
	"fmt"
	"strings"
	"sync"
	"testing"

	"golang.org/x/mod/sumdb/note"
	"golang.org/x/mod/sumdb/tlog"
)

const (
	testName        = "localhost.localdev/sumdb"
	testVerifierKey = "localhost.localdev/sumdb+00000c67+AcTrnkbUA+TU4heY3hkjiSES/DSQniBqIeQ/YppAUtK6"
	testSignerKey   = "PRIVATE+KEY+localhost.localdev/sumdb+00000c67+AXu6+oaVaOYuQOFrf1V59JK1owcFlJcHwwXHDfDGxSPk"
)

func TestClientLookup(t *testing.T) {
	tc := newTestClient(t)
	tc.mustHaveLatest(1)

	// Basic lookup.
	tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=")
	tc.mustHaveLatest(3)

	// Everything should now be cached, both for the original package and its /go.mod.
	tc.getOK = false
	tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=")
	tc.mustLookup("rsc.io/sampler", "v1.3.0/go.mod", "rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=")
	tc.mustHaveLatest(3)
	tc.getOK = true
	tc.getTileOK = false // the cache has what we need

	// Lookup with multiple returned lines.
	tc.mustLookup("rsc.io/quote", "v1.5.2", "rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=\nrsc.io/quote v1.5.2 h2:xyzzy")
	tc.mustHaveLatest(3)

	// Lookup with need for !-encoding.
	// rsc.io/Quote is the only record written after rsc.io/samper,
	// so it is the only one that should need more tiles.
	tc.getTileOK = true
	tc.mustLookup("rsc.io/Quote", "v1.5.2", "rsc.io/Quote v1.5.2 h1:uppercase!=")
	tc.mustHaveLatest(4)
}

func TestClientBadTiles(t *testing.T) {
	tc := newTestClient(t)

	flipBits := func() {
		for url, data := range tc.remote {
			if strings.Contains(url, "/tile/") {
				for i := range data {
					data[i] ^= 0x80
				}
			}
		}
	}

	// Bad tiles in initial download.
	tc.mustHaveLatest(1)
	flipBits()
	_, err := tc.client.Lookup("rsc.io/sampler", "v1.3.0")
	tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumdb.Client: checking tree#1: downloaded inconsistent tile")
	flipBits()
	tc.newClient()
	tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=")

	// Bad tiles after initial download.
	flipBits()
	_, err = tc.client.Lookup("rsc.io/Quote", "v1.5.2")
	tc.mustError(err, "rsc.io/Quote@v1.5.2: checking tree#3 against tree#4: downloaded inconsistent tile")
	flipBits()
	tc.newClient()
	tc.mustLookup("rsc.io/Quote", "v1.5.2", "rsc.io/Quote v1.5.2 h1:uppercase!=")

	// Bad starting tree hash looks like bad tiles.
	tc.newClient()
	text := tlog.FormatTree(tlog.Tree{N: 1, Hash: tlog.Hash{}})
	data, err := note.Sign(&note.Note{Text: string(text)}, tc.signer)
	if err != nil {
		tc.t.Fatal(err)
	}
	tc.config[testName+"/latest"] = data
	_, err = tc.client.Lookup("rsc.io/sampler", "v1.3.0")
	tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumdb.Client: checking tree#1: downloaded inconsistent tile")
}

func TestClientFork(t *testing.T) {
	tc := newTestClient(t)
	tc2 := tc.fork()

	tc.addRecord("rsc.io/pkg1@v1.5.2", `rsc.io/pkg1 v1.5.2 h1:hash!=
`)
	tc.addRecord("rsc.io/pkg1@v1.5.4", `rsc.io/pkg1 v1.5.4 h1:hash!=
`)
	tc.mustLookup("rsc.io/pkg1", "v1.5.2", "rsc.io/pkg1 v1.5.2 h1:hash!=")

	tc2.addRecord("rsc.io/pkg1@v1.5.3", `rsc.io/pkg1 v1.5.3 h1:hash!=
`)
	tc2.addRecord("rsc.io/pkg1@v1.5.4", `rsc.io/pkg1 v1.5.4 h1:hash!=
`)
	tc2.mustLookup("rsc.io/pkg1", "v1.5.4", "rsc.io/pkg1 v1.5.4 h1:hash!=")

	key := "/lookup/rsc.io/pkg1@v1.5.2"
	tc2.remote[key] = tc.remote[key]
	_, err := tc2.client.Lookup("rsc.io/pkg1", "v1.5.2")
	tc2.mustError(err, ErrSecurity.Error())

	/*
	   SECURITY ERROR
	   go.sum database server misbehavior detected!

	   old database:
	   	go.sum database tree!
	   	5
	   	nWzN20+pwMt62p7jbv1/NlN95ePTlHijabv5zO/s36w=

	   	— localhost.localdev/sumdb AAAMZ5/2FVAdMH58kmnz/0h299pwyskEbzDzoa2/YaPdhvLya4YWDFQQxu2TQb5GpwAH4NdWnTwuhILafisyf3CNbgg=

	   new database:
	   	go.sum database tree
	   	6
	   	wc4SkQt52o5W2nQ8To2ARs+mWuUJjss+sdleoiqxMmM=

	   	— localhost.localdev/sumdb AAAMZ6oRNswlEZ6ZZhxrCvgl1MBy+nusq4JU+TG6Fe2NihWLqOzb+y2c2kzRLoCr4tvw9o36ucQEnhc20e4nA4Qc/wc=

	   proof of misbehavior:
	   	T7i+H/8ER4nXOiw4Bj0koZOkGjkxoNvlI34GpvhHhQg=
	   	Nsuejv72de9hYNM5bqFv8rv3gm3zJQwv/DT/WNbLDLA=
	   	mOmqqZ1aI/lzS94oq/JSbj7pD8Rv9S+xDyi12BtVSHo=
	   	/7Aw5jVSMM9sFjQhaMg+iiDYPMk6decH7QLOGrL9Lx0=
	*/

	wants := []string{
		"SECURITY ERROR",
		"go.sum database server misbehavior detected!",
		"old database:\n\tgo.sum database tree\n\t5\n",
		"— localhost.localdev/sumdb AAAMZ5/2FVAd",
		"new database:\n\tgo.sum database tree\n\t6\n",
		"— localhost.localdev/sumdb AAAMZ6oRNswl",
		"proof of misbehavior:\n\tT7i+H/8ER4nXOiw4Bj0k",
	}
	text := tc2.security.String()
	for _, want := range wants {
		if !strings.Contains(text, want) {
			t.Fatalf("cannot find %q in security text:\n%s", want, text)
		}
	}
}

func TestClientGONOSUMDB(t *testing.T) {
	tc := newTestClient(t)
	tc.client.SetGONOSUMDB("p,*/q")
	tc.client.Lookup("rsc.io/sampler", "v1.3.0") // initialize before we turn off network
	tc.getOK = false

	ok := []string{
		"abc",
		"a/p",
		"pq",
		"q",
		"n/o/p/q",
	}
	skip := []string{
		"p",
		"p/x",
		"x/q",
		"x/q/z",
	}

	for _, path := range ok {
		_, err := tc.client.Lookup(path, "v1.0.0")
		if err == ErrGONOSUMDB {
			t.Errorf("Lookup(%q): ErrGONOSUMDB, wanted failed actual lookup", path)
		}
	}
	for _, path := range skip {
		_, err := tc.client.Lookup(path, "v1.0.0")
		if err != ErrGONOSUMDB {
			t.Errorf("Lookup(%q): %v, wanted ErrGONOSUMDB", path, err)
		}
	}
}

// A testClient is a self-contained client-side testing environment.
type testClient struct {
	t          *testing.T // active test
	client     *Client    // client being tested
	tileHeight int        // tile height to use (default 2)
	getOK      bool       // should tc.GetURL succeed?
	getTileOK  bool       // should tc.GetURL of tiles succeed?
	treeSize   int64
	hashes     []tlog.Hash
	remote     map[string][]byte
	signer     note.Signer

	// mu protects config, cache, log, security
	// during concurrent use of the exported methods
	// by the client itself (testClient is the Client's ClientOps,
	// and the Client methods can both read and write these fields).
	// Unexported methods invoked directly by the test
	// (for example, addRecord) need not hold the mutex:
	// for proper test execution those methods should only
	// be called when the Client is idle and not using its ClientOps.
	// Not holding the mutex in those methods ensures
	// that if a mistake is made, go test -race will report it.
	// (Holding the mutex would eliminate the race report but
	// not the underlying problem.)
	// Similarly, the get map is not protected by the mutex,
	// because the Client methods only read it.
	mu       sync.Mutex // prot
	config   map[string][]byte
	cache    map[string][]byte
	security bytes.Buffer
}

// newTestClient returns a new testClient that will call t.Fatal on error
// and has a few records already available on the remote server.
func newTestClient(t *testing.T) *testClient {
	tc := &testClient{
		t:          t,
		tileHeight: 2,
		getOK:      true,
		getTileOK:  true,
		config:     make(map[string][]byte),
		cache:      make(map[string][]byte),
		remote:     make(map[string][]byte),
	}

	tc.config["key"] = []byte(testVerifierKey + "\n")
	var err error
	tc.signer, err = note.NewSigner(testSignerKey)
	if err != nil {
		t.Fatal(err)
	}

	tc.newClient()

	tc.addRecord("rsc.io/quote@v1.5.2", `rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/quote v1.5.2 h2:xyzzy
`)

	tc.addRecord("golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c", `golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
`)
	tc.addRecord("rsc.io/sampler@v1.3.0", `rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
`)
	tc.config[testName+"/latest"] = tc.signTree(1)

	tc.addRecord("rsc.io/!quote@v1.5.2", `rsc.io/Quote v1.5.2 h1:uppercase!=
`)
	return tc
}

// newClient resets the Client associated with tc.
// This clears any in-memory cache from the Client
// but not tc's on-disk cache.
func (tc *testClient) newClient() {
	tc.client = NewClient(tc)
	tc.client.SetTileHeight(tc.tileHeight)
}

// mustLookup does a lookup for path@vers and checks that the lines that come back match want.
func (tc *testClient) mustLookup(path, vers, want string) {
	tc.t.Helper()
	lines, err := tc.client.Lookup(path, vers)
	if err != nil {
		tc.t.Fatal(err)
	}
	if strings.Join(lines, "\n") != want {
		tc.t.Fatalf("Lookup(%q, %q):\n\t%s\nwant:\n\t%s", path, vers, strings.Join(lines, "\n\t"), strings.Replace(want, "\n", "\n\t", -1))
	}
}

// mustHaveLatest checks that the on-disk configuration
// for latest is a tree of size n.
func (tc *testClient) mustHaveLatest(n int64) {
	tc.t.Helper()

	latest := tc.config[testName+"/latest"]
	lines := strings.Split(string(latest), "\n")
	if len(lines) < 2 || lines[1] != fmt.Sprint(n) {
		tc.t.Fatalf("/latest should have tree %d, but has:\n%s", n, latest)
	}
}

// mustError checks that err's error string contains the text.
func (tc *testClient) mustError(err error, text string) {
	tc.t.Helper()
	if err == nil || !strings.Contains(err.Error(), text) {
		tc.t.Fatalf("err = %v, want %q", err, text)
	}
}

// fork returns a copy of tc.
// Changes made to the new copy or to tc are not reflected in the other.
func (tc *testClient) fork() *testClient {
	tc2 := &testClient{
		t:          tc.t,
		getOK:      tc.getOK,
		getTileOK:  tc.getTileOK,
		tileHeight: tc.tileHeight,
		treeSize:   tc.treeSize,
		hashes:     append([]tlog.Hash{}, tc.hashes...),
		signer:     tc.signer,
		config:     copyMap(tc.config),
		cache:      copyMap(tc.cache),
		remote:     copyMap(tc.remote),
	}
	tc2.newClient()
	return tc2
}

func copyMap(m map[string][]byte) map[string][]byte {
	m2 := make(map[string][]byte)
	for k, v := range m {
		m2[k] = v
	}
	return m2
}

// ReadHashes is tc's implementation of tlog.HashReader, for use with
// tlog.TreeHash and so on.
func (tc *testClient) ReadHashes(indexes []int64) ([]tlog.Hash, error) {
	var list []tlog.Hash
	for _, id := range indexes {
		list = append(list, tc.hashes[id])
	}
	return list, nil
}

// addRecord adds a log record using the given (!-encoded) key and data.
func (tc *testClient) addRecord(key, data string) {
	tc.t.Helper()

	// Create record, add hashes to log tree.
	id := tc.treeSize
	tc.treeSize++
	rec, err := tlog.FormatRecord(id, []byte(data))
	if err != nil {
		tc.t.Fatal(err)
	}
	hashes, err := tlog.StoredHashesForRecordHash(id, tlog.RecordHash([]byte(data)), tc)
	if err != nil {
		tc.t.Fatal(err)
	}
	tc.hashes = append(tc.hashes, hashes...)

	// Create lookup result.
	tc.remote["/lookup/"+key] = append(rec, tc.signTree(tc.treeSize)...)

	// Create new tiles.
	tiles := tlog.NewTiles(tc.tileHeight, id, tc.treeSize)
	for _, tile := range tiles {
		data, err := tlog.ReadTileData(tile, tc)
		if err != nil {
			tc.t.Fatal(err)
		}
		tc.remote["/"+tile.Path()] = data
		// TODO delete old partial tiles
	}
}

// signTree returns the signed head for the tree of the given size.
func (tc *testClient) signTree(size int64) []byte {
	h, err := tlog.TreeHash(size, tc)
	if err != nil {
		tc.t.Fatal(err)
	}
	text := tlog.FormatTree(tlog.Tree{N: size, Hash: h})
	data, err := note.Sign(&note.Note{Text: string(text)}, tc.signer)
	if err != nil {
		tc.t.Fatal(err)
	}
	return data
}

// ReadRemote is for tc's implementation of Client.
func (tc *testClient) ReadRemote(path string) ([]byte, error) {
	// No mutex here because only the Client should be running
	// and the Client cannot change tc.get.
	if !tc.getOK {
		return nil, fmt.Errorf("disallowed remote read %s", path)
	}
	if strings.Contains(path, "/tile/") && !tc.getTileOK {
		return nil, fmt.Errorf("disallowed remote tile read %s", path)
	}

	data, ok := tc.remote[path]
	if !ok {
		return nil, fmt.Errorf("no remote path %s", path)
	}
	return data, nil
}

// ReadConfig is for tc's implementation of Client.
func (tc *testClient) ReadConfig(file string) ([]byte, error) {
	tc.mu.Lock()
	defer tc.mu.Unlock()

	data, ok := tc.config[file]
	if !ok {
		return nil, fmt.Errorf("no config %s", file)
	}
	return data, nil
}

// WriteConfig is for tc's implementation of Client.
func (tc *testClient) WriteConfig(file string, old, new []byte) error {
	tc.mu.Lock()
	defer tc.mu.Unlock()

	data := tc.config[file]
	if !bytes.Equal(old, data) {
		return ErrWriteConflict
	}
	tc.config[file] = new
	return nil
}

// ReadCache is for tc's implementation of Client.
func (tc *testClient) ReadCache(file string) ([]byte, error) {
	tc.mu.Lock()
	defer tc.mu.Unlock()

	data, ok := tc.cache[file]
	if !ok {
		return nil, fmt.Errorf("no cache %s", file)
	}
	return data, nil
}

// WriteCache is for tc's implementation of Client.
func (tc *testClient) WriteCache(file string, data []byte) {
	tc.mu.Lock()
	defer tc.mu.Unlock()

	tc.cache[file] = data
}

// Log is for tc's implementation of Client.
func (tc *testClient) Log(msg string) {
	tc.t.Log(msg)
}

// SecurityError is for tc's implementation of Client.
func (tc *testClient) SecurityError(msg string) {
	tc.mu.Lock()
	defer tc.mu.Unlock()

	fmt.Fprintf(&tc.security, "%s\n", strings.TrimRight(msg, "\n"))
}
