// +build ignore,OMIT

package mart

import (
	"bytes"
	"fmt"
	"math/rand"
	"net/http"
	"strconv"
	"strings"

	"appengine"
	"appengine/datastore"
	"appengine/mail"
	"appengine/user"

	"github.com/mjibson/appstats"
)

func init() {
	http.HandleFunc("/", front)
	http.Handle("/checkout", appstats.NewHandler(checkout))
	http.HandleFunc("/admin/populate", adminPopulate)
}

func front(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" {
		http.NotFound(w, r)
		return
	}
	fmt.Fprintf(w, "Hello, welcome to Gopher Mart!")
}

const (
	numItems = 100 // number of different items for sale

	appAdmin = "noreply@google.com" // an admin of this app, for sending mail
)

// Item represents an item for sale in Gopher Mart.
type Item struct {
	Name  string
	Price float64
}

func itemKey(c appengine.Context, i int) *datastore.Key {
	return datastore.NewKey(c, "Item", fmt.Sprintf("item%04d", i), 0, nil)
}

func checkout(c appengine.Context, w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	num, err := strconv.Atoi(r.FormValue("num"))
	if err == nil && (num < 1 || num > 30) {
		err = fmt.Errorf("%d out of range [1,30]", num)
	}
	if err != nil {
		http.Error(w, fmt.Sprintf("bad number of items: %v", err), http.StatusBadRequest)
		return
	}

	// Pick random items.
	keys := make([]*datastore.Key, num)
	for i := range keys {
		keys[i] = itemKey(c, rand.Intn(numItems))
	}

	// Dumb load.
	var items []*Item
	for _, key := range keys {
		item := new(Item)
		if err := datastore.Get(c, key, item); err != nil {
			http.Error(w, fmt.Sprintf("datastore.Get: %v", err), http.StatusBadRequest)
			return
		}
		items = append(items, item)
	}

	// Print items.
	var b bytes.Buffer
	fmt.Fprintf(&b, "Here's what you bought:\n")
	var sum float64
	for _, item := range items {
		fmt.Fprintf(&b, "\t%s", item.Name)
		fmt.Fprint(&b, strings.Repeat("\t", (40-len(item.Name)+7)/8))
		fmt.Fprintf(&b, "$%5.2f\n", item.Price)
		sum += item.Price
	}
	fmt.Fprintln(&b, strings.Repeat("-", 55))
	fmt.Fprintf(&b, "\tTotal:\t\t\t\t\t$%.2f\n", sum)

	w.Write(b.Bytes())

	sendReceipt(c, user.Current(c).Email, b.String())
}

func sendReceipt(c appengine.Context, dst, body string) {
	msg := &mail.Message{
		Sender:  appAdmin,
		To:      []string{dst},
		Subject: "Your Gopher Mart receipt",
		Body:    body,
	}
	if err := mail.Send(c, msg); err != nil {
		c.Errorf("mail.Send: %v", err)
	}
}

func adminPopulate(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	for i := range [numItems]struct{}{} { // r hates this. tee hee.
		key := itemKey(c, i)
		good := goods[rand.Intn(len(goods))]
		item := &Item{
			// TODO: vary names more
			Name:  fmt.Sprintf("%s %dg", good.name, i+1),
			Price: float64(rand.Intn(1999)+1) / 100,
		}
		if _, err := datastore.Put(c, key, item); err != nil {
			http.Error(w, err.Error(), 500)
			return
		}
	}
	fmt.Fprintf(w, "ok. %d items populated.", numItems)
}

var goods = [...]struct {
	name string
}{
	{"Gopher Bran"},
	{"Gopher Flakes"},
	{"Gopher Grease"},
	{"Gopher Litter"},
}
