// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// This example only works on Managed VMs.
// +build !appengine

package main

import (
	"html/template"
	"net/http"
	"time"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/user"
)

var initTime time.Time

type Greeting struct {
	Author  string
	Content string
	Date    time.Time
}

func main() {
	http.HandleFunc("/", handleMainPage)
	http.HandleFunc("/sign", handleSign)
	appengine.Main()
}

// guestbookKey returns the key used for all guestbook entries.
func guestbookKey(ctx context.Context) *datastore.Key {
	// The string "default_guestbook" here could be varied to have multiple guestbooks.
	return datastore.NewKey(ctx, "Guestbook", "default_guestbook", 0, nil)
}

var tpl = template.Must(template.ParseGlob("templates/*.html"))

func handleMainPage(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "GET requests only", http.StatusMethodNotAllowed)
		return
	}
	if r.URL.Path != "/" {
		http.NotFound(w, r)
		return
	}

	ctx := appengine.NewContext(r)
	tic := time.Now()
	q := datastore.NewQuery("Greeting").Ancestor(guestbookKey(ctx)).Order("-Date").Limit(10)
	var gg []*Greeting
	if _, err := q.GetAll(ctx, &gg); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Errorf(ctx, "GetAll: %v", err)
		return
	}
	log.Infof(ctx, "Datastore lookup took %s", time.Since(tic).String())
	log.Infof(ctx, "Rendering %d greetings", len(gg))

	var email, logout, login string
	if u := user.Current(ctx); u != nil {
		logout, _ = user.LogoutURL(ctx, "/")
		email = u.Email
	} else {
		login, _ = user.LoginURL(ctx, "/")
	}
	data := struct {
		Greetings            []*Greeting
		Login, Logout, Email string
	}{
		Greetings: gg,
		Login:     login,
		Logout:    logout,
		Email:     email,
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if err := tpl.ExecuteTemplate(w, "guestbook.html", data); err != nil {
		log.Errorf(ctx, "%v", err)
	}
}

func handleSign(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "POST requests only", http.StatusMethodNotAllowed)
		return
	}
	ctx := appengine.NewContext(r)
	g := &Greeting{
		Content: r.FormValue("content"),
		Date:    time.Now(),
	}
	if u := user.Current(ctx); u != nil {
		g.Author = u.String()
	}
	key := datastore.NewIncompleteKey(ctx, "Greeting", guestbookKey(ctx))
	if _, err := datastore.Put(ctx, key, g); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	// Redirect with 303 which causes the subsequent request to use GET.
	http.Redirect(w, r, "/", http.StatusSeeOther)
}
