// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

// The test uses aetest package that starts local dev_appserver and handles all requests locally:
// https://cloud.google.com/appengine/docs/standard/go/tools/localunittesting/reference
// The test requires installed appengine SDK (dev_appserver), so we guard it by aetest tag.
// Run the test with: goapp test -tags=aetest

// +build aetest

package dash

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"sync"
	"testing"
	"time"

	"github.com/google/syzkaller/dashboard/dashapi"
	"golang.org/x/net/context"
	"google.golang.org/appengine"
	"google.golang.org/appengine/aetest"
	"google.golang.org/appengine/datastore"
	aemail "google.golang.org/appengine/mail"
	"google.golang.org/appengine/user"
)

type Ctx struct {
	t          *testing.T
	inst       aetest.Instance
	ctx        context.Context
	mockedTime time.Time
	emailSink  chan *aemail.Message
}

func NewCtx(t *testing.T) *Ctx {
	t.Parallel()
	inst, err := aetest.NewInstance(&aetest.Options{
		// Without this option datastore queries return data with slight delay,
		// which fails reporting tests.
		StronglyConsistentDatastore: true,
	})
	if err != nil {
		t.Fatal(err)
	}
	r, err := inst.NewRequest("GET", "", nil)
	if err != nil {
		t.Fatal(err)
	}
	c := &Ctx{
		t:          t,
		inst:       inst,
		ctx:        appengine.NewContext(r),
		mockedTime: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
		emailSink:  make(chan *aemail.Message, 100),
	}
	registerContext(r, c)
	return c
}

func (c *Ctx) expectOK(err error) {
	if err != nil {
		c.t.Fatalf("\n%v: %v", caller(0), err)
	}
}

func (c *Ctx) expectFail(msg string, err error) {
	if err == nil {
		c.t.Fatal("\n%v: expected to fail, but it does not", caller(0))
	}
	if !strings.Contains(err.Error(), msg) {
		c.t.Fatalf("\n%v: expected to fail with %q, but failed with %q", caller(0), msg, err)
	}
}

func (c *Ctx) expectEQ(got, want interface{}) {
	if !reflect.DeepEqual(got, want) {
		c.t.Fatalf("\n%v: got %#v, want %#v", caller(0), got, want)
	}
}

func caller(skip int) string {
	_, file, line, _ := runtime.Caller(skip + 2)
	return fmt.Sprintf("%v:%v", filepath.Base(file), line)
}

func (c *Ctx) Close() {
	if !c.t.Failed() {
		// Ensure that we can render main page and all bugs in the final test state.
		c.expectOK(c.GET("/"))
		var bugs []*Bug
		keys, err := datastore.NewQuery("Bug").GetAll(c.ctx, &bugs)
		if err != nil {
			c.t.Errorf("ERROR: failed to query bugs: %v", err)
		}
		for _, key := range keys {
			c.expectOK(c.GET(fmt.Sprintf("/bug?id=%v", key.StringID())))
		}
		c.expectOK(c.GET("/email_poll"))
		for len(c.emailSink) != 0 {
			c.t.Errorf("ERROR: leftover email: %v", (<-c.emailSink).Body)
		}
	}
	unregisterContext(c)
	c.inst.Close()
}

func (c *Ctx) advanceTime(d time.Duration) {
	c.mockedTime = c.mockedTime.Add(d)
}

// API makes an api request to the app from the specified client.
func (c *Ctx) API(client, key, method string, req, reply interface{}) error {
	doer := func(r *http.Request) (*http.Response, error) {
		registerContext(r, c)
		w := httptest.NewRecorder()
		http.DefaultServeMux.ServeHTTP(w, r)
		// Later versions of Go have a nice w.Result method,
		// but we stuck on 1.6 on appengine.
		if w.Body == nil {
			w.Body = new(bytes.Buffer)
		}
		res := &http.Response{
			StatusCode: w.Code,
			Status:     http.StatusText(w.Code),
			Body:       ioutil.NopCloser(bytes.NewReader(w.Body.Bytes())),
		}
		return res, nil
	}

	c.t.Logf("API(%v): %#v", method, req)
	err := dashapi.Query(client, "", key, method, c.inst.NewRequest, doer, req, reply)
	if err != nil {
		c.t.Logf("ERROR: %v", err)
		return err
	}
	c.t.Logf("REPLY: %#v", reply)
	return nil
}

// GET sends authorized HTTP GET request to the app.
func (c *Ctx) GET(url string) error {
	return c.httpRequest("GET", url, "")
}

// POST sends authorized HTTP POST request to the app.
func (c *Ctx) POST(url, body string) error {
	return c.httpRequest("POST", url, body)
}

func (c *Ctx) httpRequest(method, url, body string) error {
	c.t.Logf("%v: %v", method, url)
	r, err := c.inst.NewRequest(method, url, strings.NewReader(body))
	if err != nil {
		c.t.Fatal(err)
	}
	registerContext(r, c)
	user := &user.User{
		Email:      "test@syzkaller.com",
		AuthDomain: "gmail.com",
		Admin:      true,
	}
	aetest.Login(user, r)
	w := httptest.NewRecorder()
	http.DefaultServeMux.ServeHTTP(w, r)
	c.t.Logf("REPLY: %v", w.Code)
	if w.Code != http.StatusOK {
		return fmt.Errorf("%v", w.Body.String())
	}
	return nil
}

func (c *Ctx) incomingEmail(to, body string) {
	email := fmt.Sprintf(`Sender: foo@bar.com
Date: Tue, 15 Aug 2017 14:59:00 -0700
Message-ID: <1234>
Subject: crash1
From: default@sender.com
Cc: test@syzkaller.com, bugs@syzkaller.com
To: %v
Content-Type: text/plain

%v
`, to, body)
	c.expectOK(c.POST("/_ah/mail/", email))
}

func init() {
	// Mock time as some functionality relies on real time.
	timeNow = func(c context.Context) time.Time {
		return getRequestContext(c).mockedTime
	}
	sendEmail = func(c context.Context, msg *aemail.Message) error {
		getRequestContext(c).emailSink <- msg
		return nil
	}
}

// Machinery to associate mocked time with requests.
type RequestMapping struct {
	c   context.Context
	ctx *Ctx
}

var (
	requestMu       sync.Mutex
	requestContexts []RequestMapping
)

func registerContext(r *http.Request, c *Ctx) {
	requestMu.Lock()
	defer requestMu.Unlock()
	requestContexts = append(requestContexts, RequestMapping{appengine.NewContext(r), c})
}

func getRequestContext(c context.Context) *Ctx {
	requestMu.Lock()
	defer requestMu.Unlock()
	for _, m := range requestContexts {
		if reflect.DeepEqual(c, m.c) {
			return m.ctx
		}
	}
	panic(fmt.Sprintf("no context for: %#v", c))
}

func unregisterContext(c *Ctx) {
	requestMu.Lock()
	defer requestMu.Unlock()
	n := 0
	for _, m := range requestContexts {
		if m.ctx == c {
			continue
		}
		requestContexts[n] = m
		n++
	}
	requestContexts = requestContexts[:n]
}
