// 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) {
	do(t, "GET", "/", func(r *http.Request) {
		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
	}()

	do(t, "GET", "/"+importPath, func(r *http.Request) {
		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) {
	do(t, "GET", "/"+importPath, func(r *http.Request) {
		cachedPresentation := "<div>My Presentation</div>"

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

		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 w.Body.String() != cachedPresentation {
			t.Fatal("response does not matched cached presentation")
		}
	})
}

func TestPresentationNotFound(t *testing.T) {
	do(t, "GET", "/"+importPath, func(r *http.Request) {
		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) {
	do(t, "POST", "/", func(r *http.Request) {
		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()

	defer func(old string) { playCompileUrl = old }(playCompileUrl)
	playCompileUrl = server.URL

	do(t, "POST", "/compile", func(r *http.Request) {
		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) {
	do(t, "GET", "/bot.html", func(r *http.Request) {
		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)
		}
	})
}

func do(t *testing.T, method, path string, f func(*http.Request)) {
	i, err := aetest.NewInstance(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer i.Close()

	r, err := i.NewRequest(method, path, nil)
	if err != nil {
		t.Fatal(err)
	}

	f(r)
}
