// Copyright 2021 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 client

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"path"
	"reflect"
	"runtime"
	"testing"
	"time"

	"golang.org/x/vulndb/osv"
)

var testVuln string = `[
	{"ID":"ID","Package":{"Name":"golang.org/example/one","Ecosystem":"go"}, "Summary":"",
	 "Severity":2,"Affects":{"Ranges":[{"Type":"SEMVER","Introduced":"","Fixed":"v2.2.0"}]},
	 "ecosystem_specific":{"Symbols":["some_symbol_1"]
	}}]`

// index containing timestamps for package in testVuln.
var index string = `{
	"golang.org/example/one": "2020-03-09T10:00:00.81362141-07:00"
	}`

func serveTestVuln(w http.ResponseWriter, req *http.Request) {
	fmt.Fprint(w, testVuln)
}

func serveIndex(w http.ResponseWriter, req *http.Request) {
	fmt.Fprint(w, index)
}

// testCache for testing purposes
type testCache struct {
	indexMap   map[string]osv.DBIndex
	indexStamp map[string]time.Time
	vulnMap    map[string]map[string][]*osv.Entry
}

func freshTestCache() *testCache {
	return &testCache{
		indexMap:   make(map[string]osv.DBIndex),
		indexStamp: make(map[string]time.Time),
		vulnMap:    make(map[string]map[string][]*osv.Entry),
	}
}

func (tc *testCache) ReadIndex(db string) (osv.DBIndex, time.Time, error) {
	index, ok := tc.indexMap[db]
	if !ok {
		return nil, time.Time{}, nil
	}
	stamp, ok := tc.indexStamp[db]
	if !ok {
		return nil, time.Time{}, nil
	}
	return index, stamp, nil
}

func (tc *testCache) WriteIndex(db string, index osv.DBIndex, stamp time.Time) error {
	tc.indexMap[db] = index
	tc.indexStamp[db] = stamp
	return nil
}

func (tc *testCache) ReadEntries(db, module string) ([]*osv.Entry, error) {
	mMap, ok := tc.vulnMap[db]
	if !ok {
		return nil, nil
	}
	return mMap[module], nil
}

func (tc *testCache) WriteEntries(db, module string, entries []*osv.Entry) error {
	mMap, ok := tc.vulnMap[db]
	if !ok {
		mMap = make(map[string][]*osv.Entry)
		tc.vulnMap[db] = mMap
	}
	mMap[module] = append(mMap[module], entries...)
	return nil
}

// cachedTestVuln returns a function creating a local cache
// for db with `dbName` with a version of testVuln where
// Summary="cached" and LastModified happened after entry
// in the `index` for the same pkg.
func cachedTestVuln(dbName string) Cache {
	c := freshTestCache()
	e := &osv.Entry{
		ID:       "ID1",
		Details:  "cached",
		Modified: time.Now(),
	}
	c.WriteEntries(dbName, "golang.org/example/one", []*osv.Entry{e})
	return c
}

// createDirAndFile creates a directory `dir` if such directory does
// not exist and creates a `file` with `content` in the directory.
func createDirAndFile(dir, file, content string) error {
	if err := os.MkdirAll(dir, 0755); err != nil {
		return err
	}
	return ioutil.WriteFile(path.Join(dir, file), []byte(content), 0644)
}

// localDB creates a local db with testVuln1, testVuln2, and index as contents.
func localDB(t *testing.T) (string, error) {
	dbName := t.TempDir()

	if err := createDirAndFile(path.Join(dbName, "/golang.org/example/"), "one.json", testVuln); err != nil {
		return "", err
	}
	if err := createDirAndFile(path.Join(dbName, ""), "index.json", index); err != nil {
		return "", err
	}
	return dbName, nil
}

func TestClient(t *testing.T) {
	if runtime.GOOS == "js" {
		t.Skip("skipping test: no network on js")
	}

	// Create a local http database.
	http.HandleFunc("/golang.org/example/one.json", serveTestVuln)
	http.HandleFunc("/index.json", serveIndex)

	l, err := net.Listen("tcp", "127.0.0.1:")
	if err != nil {
		t.Fatalf("failed to listen on 127.0.0.1: %s", err)
	}
	_, port, _ := net.SplitHostPort(l.Addr().String())
	go func() { http.Serve(l, nil) }()

	// Create a local file database.
	localDBName, err := localDB(t)
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(localDBName)

	for _, test := range []struct {
		name   string
		source string
		cache  Cache
		// cache summary for testVuln
		summary string
	}{
		// Test the http client without any cache.
		{name: "http-no-cache", source: "http://localhost:" + port, cache: nil, summary: ""},
		// Test the http client with empty cache.
		{name: "http-empty-cache", source: "http://localhost:" + port, cache: freshTestCache(), summary: ""},
		// Test the client with non-stale cache containing a version of testVuln2 where Summary="cached".
		{name: "http-cache", source: "http://localhost:" + port, cache: cachedTestVuln("localhost"), summary: "cached"},
		// Repeat the same for local file client.
		{name: "file-no-cache", source: "file://" + localDBName, cache: nil, summary: ""},
		{name: "file-empty-cache", source: "file://" + localDBName, cache: freshTestCache(), summary: ""},
		// Cache does not play a role in local file databases.
		{name: "file-cache", source: "file://" + localDBName, cache: cachedTestVuln(localDBName), summary: ""},
	} {
		client, err := NewClient([]string{test.source}, Options{HTTPCache: test.cache})
		if err != nil {
			t.Fatal(err)
		}

		vulns, err := client.Get("golang.org/example/one")
		if err != nil {
			t.Fatal(err)
		}

		if len(vulns) != 1 {
			t.Errorf("%s: want 1 vuln for golang.org/example/one; got %v", test.name, len(vulns))
		}

		if v := vulns[0]; v.Details != test.summary {
			t.Errorf("%s: want '%s' summary for testVuln; got '%s'", test.name, test.summary, v.Details)
		}
	}
}

func TestCorrectFetchesNoCache(t *testing.T) {
	fetches := map[string]int{}
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fetches[r.URL.Path]++
		if r.URL.Path == "/index.json" {
			j, _ := json.Marshal(osv.DBIndex{
				"a": time.Now(),
				"b": time.Now(),
			})
			w.Write(j)
		} else {
			w.Write([]byte("[]"))
		}
	}))
	defer ts.Close()

	hs := &httpSource{url: ts.URL, c: new(http.Client)}
	for _, module := range []string{"a", "b", "c"} {
		if _, err := hs.Get(module); err != nil {
			t.Fatalf("unexpected error: %s", err)
		}
	}
	expectedFetches := map[string]int{"/index.json": 3, "/a.json": 1, "/b.json": 1}
	if !reflect.DeepEqual(fetches, expectedFetches) {
		t.Errorf("unexpected fetches, got %v, want %v", fetches, expectedFetches)
	}
}

// Make sure that a cached index is used in the case it is stale
// but there were no changes to it at the server side.
func TestCorrectFetchesNoChangeIndex(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/index.json" {
			w.WriteHeader(http.StatusNotModified)
		}
	}))
	defer ts.Close()
	url, _ := url.Parse(ts.URL)

	// set timestamp so that cached index is stale,
	// i.e., more than two hours old.
	timeStamp := time.Now().Add(time.Hour * (-3))
	index := osv.DBIndex{"a": timeStamp}
	cache := freshTestCache()
	cache.WriteIndex(url.Hostname(), index, timeStamp)

	e := &osv.Entry{
		ID:       "ID1",
		Modified: timeStamp,
	}
	cache.WriteEntries(url.Hostname(), "a", []*osv.Entry{e})

	client, err := NewClient([]string{ts.URL}, Options{HTTPCache: cache})
	if err != nil {
		t.Fatal(err)
	}
	vulns, err := client.Get("a")
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(vulns, []*osv.Entry{e}) {
		t.Errorf("want %v vuln; got %v", e, vulns)
	}
}
