// Copyright 2013 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 or at
// https://developers.google.com/open-source/licenses/bsd.

package database

import (
	"math"
	"reflect"
	"strconv"
	"testing"
	"time"

	"github.com/garyburd/redigo/redis"
	"google.golang.org/appengine/aetest"

	"github.com/golang/gddo/doc"
)

func newDB(t *testing.T) *Database {
	p := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second)
		if err != nil {
			return nil, err
		}
		_, err = c.Do("SELECT", "9")
		if err != nil {
			c.Close()
			return nil, err
		}
		return c, nil
	}, 1)

	c := p.Get()
	defer c.Close()
	n, err := redis.Int(c.Do("DBSIZE"))
	if n != 0 || err != nil {
		t.Errorf("DBSIZE returned %d, %v", n, err)
	}

	ctx, done, err := aetest.NewContext()
	if err != nil {
		t.Fatal(err)
	}
	defer done()

	return &Database{Pool: p, AppEngineContext: ctx}
}

func closeDB(db *Database) {
	c := db.Pool.Get()
	c.Do("FLUSHDB")
	c.Close()
}

func TestPutGet(t *testing.T) {
	var nextCrawl = time.Unix(time.Now().Add(time.Hour).Unix(), 0).UTC()

	db := newDB(t)
	defer closeDB(db)
	pdoc := &doc.Package{
		ImportPath:  "github.com/user/repo/foo/bar",
		Name:        "bar",
		Synopsis:    "hello",
		ProjectRoot: "github.com/user/repo",
		ProjectName: "foo",
		Updated:     time.Now().Add(-time.Hour),
		Imports:     []string{"C", "errors", "github.com/user/repo/foo/bar"}, // self import for testing convenience.
	}
	if err := db.Put(pdoc, nextCrawl, false); err != nil {
		t.Errorf("db.Put() returned error %v", err)
	}
	if err := db.Put(pdoc, time.Time{}, false); err != nil {
		t.Errorf("second db.Put() returned error %v", err)
	}

	actualPdoc, actualSubdirs, actualCrawl, err := db.Get("github.com/user/repo/foo/bar")
	if err != nil {
		t.Fatalf("db.Get(.../foo/bar) returned %v", err)
	}
	if len(actualSubdirs) != 0 {
		t.Errorf("db.Get(.../foo/bar) returned subdirs %v, want none", actualSubdirs)
	}
	if !reflect.DeepEqual(actualPdoc, pdoc) {
		t.Errorf("db.Get(.../foo/bar) returned doc %v, want %v", actualPdoc, pdoc)
	}
	if !nextCrawl.Equal(actualCrawl) {
		t.Errorf("db.Get(.../foo/bar) returned crawl %v, want %v", actualCrawl, nextCrawl)
	}

	before := time.Now().Unix()
	if err := db.BumpCrawl(pdoc.ProjectRoot); err != nil {
		t.Errorf("db.BumpCrawl() returned %v", err)
	}
	after := time.Now().Unix()

	_, _, actualCrawl, _ = db.Get("github.com/user/repo/foo/bar")
	if actualCrawl.Unix() < before || after < actualCrawl.Unix() {
		t.Errorf("actualCrawl=%v, expect value between %v and %v", actualCrawl.Unix(), before, after)
	}

	// Popular

	if err := db.IncrementPopularScore(pdoc.ImportPath); err != nil {
		t.Errorf("db.IncrementPopularScore() returned %v", err)
	}

	// Get "-"

	actualPdoc, _, _, err = db.Get("-")
	if err != nil {
		t.Fatalf("db.Get(-) returned %v", err)
	}
	if !reflect.DeepEqual(actualPdoc, pdoc) {
		t.Errorf("db.Get(-) returned doc %v, want %v", actualPdoc, pdoc)
	}

	actualPdoc, actualSubdirs, _, err = db.Get("github.com/user/repo/foo")
	if err != nil {
		t.Fatalf("db.Get(.../foo) returned %v", err)
	}
	if actualPdoc != nil {
		t.Errorf("db.Get(.../foo) returned doc %v, want %v", actualPdoc, nil)
	}
	expectedSubdirs := []Package{{Path: "github.com/user/repo/foo/bar", Synopsis: "hello"}}
	if !reflect.DeepEqual(actualSubdirs, expectedSubdirs) {
		t.Errorf("db.Get(.../foo) returned subdirs %v, want %v", actualSubdirs, expectedSubdirs)
	}
	actualImporters, err := db.Importers("github.com/user/repo/foo/bar")
	if err != nil {
		t.Fatalf("db.Importers() returned error %v", err)
	}
	expectedImporters := []Package{{Path: "github.com/user/repo/foo/bar", Synopsis: "hello"}}
	if !reflect.DeepEqual(actualImporters, expectedImporters) {
		t.Errorf("db.Importers() = %v, want %v", actualImporters, expectedImporters)
	}
	actualImports, err := db.Packages(pdoc.Imports)
	if err != nil {
		t.Fatalf("db.Imports() returned error %v", err)
	}
	for i := range actualImports {
		if actualImports[i].Path == "C" {
			actualImports[i].Synopsis = ""
		}
	}
	expectedImports := []Package{
		{Path: "C", Synopsis: ""},
		{Path: "errors", Synopsis: ""},
		{Path: "github.com/user/repo/foo/bar", Synopsis: "hello"},
	}
	if !reflect.DeepEqual(actualImports, expectedImports) {
		t.Errorf("db.Imports() = %v, want %v", actualImports, expectedImports)
	}
	importerCount, _ := db.ImporterCount("github.com/user/repo/foo/bar")
	if importerCount != 1 {
		t.Errorf("db.ImporterCount() = %d, want %d", importerCount, 1)
	}
	if err := db.Delete("github.com/user/repo/foo/bar"); err != nil {
		t.Errorf("db.Delete() returned error %v", err)
	}

	db.Query("bar")

	if err := db.Put(pdoc, time.Time{}, false); err != nil {
		t.Errorf("db.Put() returned error %v", err)
	}

	if err := db.Block("github.com/user/repo"); err != nil {
		t.Errorf("db.Block() returned error %v", err)
	}

	blocked, err := db.IsBlocked("github.com/user/repo/foo/bar")
	if !blocked || err != nil {
		t.Errorf("db.IsBlocked(github.com/user/repo/foo/bar) returned %v, %v, want true, nil", blocked, err)
	}

	blocked, err = db.IsBlocked("github.com/foo/bar")
	if blocked || err != nil {
		t.Errorf("db.IsBlocked(github.com/foo/bar) returned %v, %v, want false, nil", blocked, err)
	}

	c := db.Pool.Get()
	defer c.Close()
	c.Send("DEL", "maxQueryId")
	c.Send("DEL", "maxPackageId")
	c.Send("DEL", "block")
	c.Send("DEL", "popular:0")
	c.Send("DEL", "newCrawl")
	keys, err := redis.Values(c.Do("HKEYS", "ids"))
	for _, key := range keys {
		t.Errorf("unexpected id %s", key)
	}
	keys, err = redis.Values(c.Do("KEYS", "*"))
	for _, key := range keys {
		t.Errorf("unexpected key %s", key)
	}
}

const epsilon = 0.000001

func TestPopular(t *testing.T) {
	db := newDB(t)
	defer closeDB(db)
	c := db.Pool.Get()
	defer c.Close()

	// Add scores for packages. On each iteration, add half-life to time and
	// divide the score by two. All packages should have the same score.

	now := time.Now()
	score := float64(4048)
	for id := 12; id >= 0; id-- {
		path := "github.com/user/repo/p" + strconv.Itoa(id)
		c.Do("HSET", "ids", path, id)
		err := db.incrementPopularScoreInternal(path, score, now)
		if err != nil {
			t.Fatal(err)
		}
		now = now.Add(popularHalfLife)
		score /= 2
	}

	values, _ := redis.Values(c.Do("ZRANGE", "popular", "0", "100000", "WITHSCORES"))
	if len(values) != 26 {
		t.Fatalf("Expected 26 values, got %d", len(values))
	}

	// Check for equal scores.
	score, err := redis.Float64(values[1], nil)
	if err != nil {
		t.Fatal(err)
	}
	for i := 3; i < len(values); i += 2 {
		s, _ := redis.Float64(values[i], nil)
		if math.Abs(score-s)/score > epsilon {
			t.Errorf("Bad score, score[1]=%g, score[%d]=%g", score, i, s)
		}
	}
}

func TestCounter(t *testing.T) {
	db := newDB(t)
	defer closeDB(db)

	const key = "127.0.0.1"

	now := time.Now()
	n, err := db.incrementCounterInternal(key, 1, now)
	if err != nil {
		t.Fatal(err)
	}
	if math.Abs(n-1.0) > epsilon {
		t.Errorf("1: got n=%g, want 1", n)
	}
	n, err = db.incrementCounterInternal(key, 1, now)
	if err != nil {
		t.Fatal(err)
	}
	if math.Abs(n-2.0)/2.0 > epsilon {
		t.Errorf("2: got n=%g, want 2", n)
	}
	now = now.Add(counterHalflife)
	n, err = db.incrementCounterInternal(key, 1, now)
	if err != nil {
		t.Fatal(err)
	}
	if math.Abs(n-2.0)/2.0 > epsilon {
		t.Errorf("3: got n=%g, want 2", n)
	}
}
