package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"time"

	"code.justin.tv/common/chitin"
	"code.justin.tv/common/chitin/clog"
	"github.com/zenazn/goji/graceful"
	"golang.org/x/net/context"
)

func init() {
	http.HandleFunc("/", handleHello)
	http.HandleFunc("/self", handleSelf)
	http.HandleFunc("/sleep", handleSleep)
	http.HandleFunc("/panic", handlePanic)
}

func main() {
	graceful.HandleSignals()

	l, err := net.Listen("tcp", "localhost:8080")
	if err != nil {
		log.Fatalf("bind=%q", err)
	}
	log.Printf("server=%q", "listening")

	ctx, err := chitin.ExperimentalTraceContext(context.Background())
	if err != nil {
		log.Fatalf("trace=%q", err)
	}

	handler := chitin.Handler(http.DefaultServeMux, chitin.SetBaseContext(ctx))
	err = graceful.Serve(l, handler)
	if err != nil {
		log.Fatalf("serve=%q", err)
	}
	log.Printf("server=%q", "draining")
	graceful.Wait()
	log.Printf("server=%q", "done")
}

func handleHello(w http.ResponseWriter, r *http.Request) {
	ctx := chitin.Context(w, r)
	clog.Log(ctx).Printf("url=%q", r.URL)

	_, err := io.Copy(ioutil.Discard, r.Body)
	if err != nil {
		clog.Log(ctx).Printf("body-read-err=%q", err)
		return
	}

	fmt.Fprintf(w, "Hello, %q", r.URL)
}

func handleSleep(w http.ResponseWriter, r *http.Request) {
	time.Sleep(5 * time.Second)
	w.WriteHeader(http.StatusOK)
	w.(http.Flusher).Flush()
	time.Sleep(10 * time.Second)
}

func handlePanic(w http.ResponseWriter, r *http.Request) {
	panic("oops")
}

func handleSelf(w http.ResponseWriter, r *http.Request) {
	ctx := chitin.Context(w, r)
	resp, err := chitin.Client(ctx).Get("http://localhost:8080/sleep")
	if err != nil {
		clog.Log(ctx).Printf("err=%q", err)
		return
	}
	defer resp.Body.Close()
	io.Copy(ioutil.Discard, resp.Body)
}
