// Copyright 2015 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 talksapp

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"testing"
	"time"

	"github.com/golang/gddo/gosrc"

	"appengine"
	"appengine/aetest"
	"appengine/memcache"
)

const importPath = "github.com/user/repo/path/to/presentation.slide"

func TestHome(t *testing.T) {
	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest("GET", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()

	handlerFunc(serveRoot).ServeHTTP(w, r)

	if w.Code != http.StatusOK {
		t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code)
	}

	if !strings.Contains(w.Body.String(), "go-talks.appspot.org") {
		t.Fatal("expected response to contain: go-talks.appspot.org")
	}
}

func TestPresentation(t *testing.T) {
	presentationTitle := "My awesome presentation!"
	presentationSrc := []byte(presentationTitle + `

Subtitle

* Slide 1

- Foo
- Bar
- Baz
`)

	originalGetPresentation := getPresentation
	getPresentation = func(client *http.Client, importPath string) (*gosrc.Presentation, error) {
		return &gosrc.Presentation{
			Filename: "presentation.slide",
			Files: map[string][]byte{
				"presentation.slide": presentationSrc,
			},
		}, nil
	}
	defer func() {
		getPresentation = originalGetPresentation
	}()

	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest("GET", "/"+importPath, nil)
	if err != nil {
		t.Fatal(err)
	}
	w := httptest.NewRecorder()

	handlerFunc(serveRoot).ServeHTTP(w, r)

	if w.Code != http.StatusOK {
		t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code)
	}

	if !strings.Contains(w.Body.String(), presentationTitle) {
		t.Fatalf("unexpected response body: %s", w.Body)
	}

	c := appengine.NewContext(r)
	_, err = memcache.Get(c, importPath)

	if err == memcache.ErrCacheMiss {
		t.Fatal("expected result to be cached")
	}

	if err != nil {
		t.Fatalf("expected no error, got: %s", err)
	}
}

func TestPresentationCacheHit(t *testing.T) {
	cachedPresentation := "<div>My Presentation</div>"

	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest("GET", "/"+importPath, nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()

	c := appengine.NewContext(r)
	memcache.Add(c, &memcache.Item{
		Key:        importPath,
		Value:      []byte(cachedPresentation),
		Expiration: time.Hour,
	})

	handlerFunc(serveRoot).ServeHTTP(w, r)

	if w.Code != http.StatusOK {
		t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code)
	}

	if w.Body.String() != cachedPresentation {
		t.Fatal("response does not matched cached presentation")
	}
}

func TestPresentationNotFound(t *testing.T) {
	originalGetPresentation := getPresentation
	getPresentation = func(client *http.Client, importPath string) (*gosrc.Presentation, error) {
		return nil, gosrc.NotFoundError{}
	}
	defer func() {
		getPresentation = originalGetPresentation
	}()

	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest("GET", "/"+importPath, nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()

	handlerFunc(serveRoot).ServeHTTP(w, r)

	if w.Code != http.StatusBadRequest {
		t.Fatalf("expected status: %d, got: %d", http.StatusBadRequest, w.Code)
	}
}

func TestWrongMethod(t *testing.T) {
	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest("POST", "/", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()

	handlerFunc(serveRoot).ServeHTTP(w, r)

	if w.Code != http.StatusMethodNotAllowed {
		t.Fatalf("expected status %d", http.StatusMethodNotAllowed)
	}
}

func TestCompile(t *testing.T) {
	version := "2"
	body := `
	package main

	import "fmt"

	func main() {
		fmt.fmtPrintln("Hello, playground")
	}
	`
	responseJSON := `{"Errors":"","Events":[{"Message":"Hello, playground\n","Kind":"stdout","Delay":0}]}`

	server := httptest.NewServer(
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			formVersion := r.FormValue("version")
			formBody := r.FormValue("body")

			if formVersion != version {
				t.Fatal("expected version sent to play.golang.org to be: %s, was: %s", version, formVersion)
			}

			if formBody != body {
				t.Fatal("expected body sent to play.golang.org to be: %s, was: %s", body, formBody)
			}

			w.Header().Set("Content-Type", "application/json")
			w.WriteHeader(200)

			fmt.Fprintln(w, responseJSON)
		}),
	)
	defer server.Close()

	originalPlayCompileUrl := playCompileUrl
	playCompileUrl = server.URL
	defer func() {
		playCompileUrl = originalPlayCompileUrl
	}()

	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest("POST", "/compile", nil)
	if err != nil {
		t.Fatal(err)
	}

	r.PostForm = url.Values{
		"version": []string{version},
		"body":    []string{body},
	}

	w := httptest.NewRecorder()

	handlerFunc(serveCompile).ServeHTTP(w, r)

	if w.Code != http.StatusOK {
		t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code)
	}

	contentType := w.Header().Get("Content-Type")
	if w.Header().Get("Content-Type") != "application/json" {
		t.Fatalf("unexpected Content-Type: %s", contentType)
	}

	if strings.TrimSpace(w.Body.String()) != responseJSON {
		t.Fatalf("unexpected response body: %s", w.Body)
	}
}

func TestBot(t *testing.T) {
	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest("GET", "/bot.html", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()

	handlerFunc(serveBot).ServeHTTP(w, r)

	if w.Code != http.StatusOK {
		t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code)
	}

	if !strings.Contains(w.Body.String(), contactEmail) {
		t.Fatalf("expected body to contain %s", contactEmail)
	}
}
