// 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 sumweb

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

	"golang.org/x/exp/notary/internal/note"
	"golang.org/x/exp/notary/internal/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 TestConnLookup(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 TestConnBadTiles(t *testing.T) {
	tc := newTestClient(t)

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

	// Bad tiles in initial download.
	tc.mustHaveLatest(1)
	flipBits()
	_, err := tc.conn.Lookup("rsc.io/sampler", "v1.3.0")
	tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumweb.Conn: checking tree#1: downloaded inconsistent tile")
	flipBits()
	tc.newConn()
	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.conn.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.newConn()
	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.newConn()
	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.conn.Lookup("rsc.io/sampler", "v1.3.0")
	tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumweb.Conn: checking tree#1: downloaded inconsistent tile")
}

func TestConnFork(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 := "https://" + testName + "/lookup/rsc.io/pkg1@v1.5.2"
	tc2.get[key] = tc.get[key]
	_, err := tc2.conn.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)
		}
	}
}

// A testClient is a self-contained client-side testing environment.
type testClient struct {
	t          *testing.T // active test
	conn       *Conn      // conn 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
	get        map[string][]byte
	signer     note.Signer

	// mu protects config, cache, log, security
	// during concurrent use of the exported methods
	// by the conn itself (testClient is the Conn's Client,
	// 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 Conn is idle and not using its Client.
	// 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),
		get:        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.newConn()

	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
}

// newConn resets the Conn associated with tc.
// This clears any in-memory cache from the Conn
// but not tc's on-disk cache.
func (tc *testClient) newConn() {
	tc.conn = NewConn(tc)
	tc.conn.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.conn.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),
		get:        copyMap(tc.get),
	}
	tc2.newConn()
	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.get["https://"+testName+"/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.get["https://"+testName+"/"+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
}

// GetURL is for tc's implementation of Client.
func (tc *testClient) GetURL(url 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 URL %s", url)
	}
	if strings.Contains(url, "/tile/") && !tc.getTileOK {
		return nil, fmt.Errorf("disallowed Tile URL %s", url)
	}

	data, ok := tc.get[url]
	if !ok {
		return nil, fmt.Errorf("no URL %s", url)
	}
	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"))
}
