// +build ignore,OMIT

package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"net/http"
)

type errorHandler func(http.ResponseWriter, *http.Request) error

func handleError(f errorHandler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		err := f(w, r)
		if err != nil {
			log.Printf("%v", err)
			http.Error(w, "Oops!", http.StatusInternalServerError)
		}
	}
}

func handler(w http.ResponseWriter, r *http.Request) error {
	name := r.FormValue("name")
	if name == "" {
		return fmt.Errorf("empty name")
	}
	fmt.Fprintln(w, "Hi,", name)
	return nil
}

// resp implements http.ResponseWriter writing
type dummyResp struct {
	io.Writer
	h int
}

func newDummyResp() http.ResponseWriter {
	return &dummyResp{Writer: &bytes.Buffer{}}
}

func (w *dummyResp) Header() http.Header { return make(http.Header) }
func (w *dummyResp) WriteHeader(h int)   { w.h = h }
func (w *dummyResp) String() string      { return fmt.Sprintf("[%v] %q", w.h, w.Writer) }

func main() {
	http.HandleFunc("/hi", handleError(handler))

	// ListenAndServe is not allowed on the playground.
	// http.ListenAndServe(":8080", nil)

	// In the playground we call the handler manually with dummy requests.

	// Fake request without 'name' parameter.
	r := &http.Request{}
	w := newDummyResp()
	handleError(handler)(w, r)
	fmt.Println("resp a:", w)

	// Fake request with 'name' parameter 'john'.
	r.Form["name"] = []string{"john"}
	w = newDummyResp()
	handleError(handler)(w, r)
	fmt.Println("resp b:", w)

}
