// Copyright 2009 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.

package main

import (
	"bytes";
	"bufio";
	"expvar";
	"flag";
	"fmt";
	"io";
	"log";
	"net";
	"os";
	"strconv";
)


// hello world, the web server
var helloRequests = expvar.NewInt("hello-requests")

func HelloServer(c *http.Conn, req *http.Request) {
	helloRequests.Add(1);
	io.WriteString(c, "hello, world!\n");
}

// Simple counter server. POSTing to it will set the value.
type Counter struct {
	n int;
}

// This makes Counter satisfy the expvar.Var interface, so we can export
// it directly.
func (ctr *Counter) String() string	{ return fmt.Sprintf("%d", ctr.n) }

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
	switch req.Method {
	case "GET":
		ctr.n++
	case "POST":
		buf := new(bytes.Buffer);
		io.Copy(buf, req.Body);
		body := buf.String();
		if n, err := strconv.Atoi(body); err != nil {
			fmt.Fprintf(c, "bad POST: %v\nbody: [%v]\n", err, body)
		} else {
			ctr.n = n;
			fmt.Fprint(c, "counter reset\n");
		}
	}
	fmt.Fprintf(c, "counter = %d\n", ctr.n);
}

// simple file server
var webroot = flag.String("root", "/home/rsc", "web root directory")
var pathVar = expvar.NewMap("file-requests")

func FileServer(c *http.Conn, req *http.Request) {
	c.SetHeader("content-type", "text/plain; charset=utf-8");
	pathVar.Add(req.URL.Path, 1);
	path := *webroot + req.URL.Path;	// TODO: insecure: use os.CleanName
	f, err := os.Open(path, os.O_RDONLY, 0);
	if err != nil {
		c.WriteHeader(http.StatusNotFound);
		fmt.Fprintf(c, "open %s: %v\n", path, err);
		return;
	}
	n, err1 := io.Copy(c, f);
	fmt.Fprintf(c, "[%d bytes]\n", n);
	f.Close();
}

// simple flag server
var booleanflag = flag.Bool("boolean", true, "another flag for testing")

func FlagServer(c *http.Conn, req *http.Request) {
	c.SetHeader("content-type", "text/plain; charset=utf-8");
	fmt.Fprint(c, "Flags:\n");
	flag.VisitAll(func(f *flag.Flag) {
		if f.Value.String() != f.DefValue {
			fmt.Fprintf(c, "%s = %s [default = %s]\n", f.Name, f.Value.String(), f.DefValue)
		} else {
			fmt.Fprintf(c, "%s = %s\n", f.Name, f.Value.String())
		}
	});
}

// simple argument server
func ArgServer(c *http.Conn, req *http.Request) {
	for i, s := range os.Args {
		fmt.Fprint(c, s, " ")
	}
}

// a channel (just for the fun of it)
type Chan chan int

func ChanCreate() Chan {
	c := make(Chan);
	go func(c Chan) {
		for x := 0; ; x++ {
			c <- x
		}
	}(c);
	return c;
}

func (ch Chan) ServeHTTP(c *http.Conn, req *http.Request) {
	io.WriteString(c, fmt.Sprintf("channel send #%d\n", <-ch))
}

// exec a program, redirecting output
func DateServer(c *http.Conn, req *http.Request) {
	c.SetHeader("content-type", "text/plain; charset=utf-8");
	r, w, err := os.Pipe();
	if err != nil {
		fmt.Fprintf(c, "pipe: %s\n", err);
		return;
	}
	pid, err := os.ForkExec("/bin/date", []string{"date"}, os.Environ(), "", []*os.File{nil, w, w});
	defer r.Close();
	w.Close();
	if err != nil {
		fmt.Fprintf(c, "fork/exec: %s\n", err);
		return;
	}
	io.Copy(c, r);
	wait, err := os.Wait(pid, 0);
	if err != nil {
		fmt.Fprintf(c, "wait: %s\n", err);
		return;
	}
	if !wait.Exited() || wait.ExitStatus() != 0 {
		fmt.Fprintf(c, "date: %v\n", wait);
		return;
	}
}

func main() {
	flag.Parse();

	// The counter is published as a variable directly.
	ctr := new(Counter);
	http.Handle("/counter", ctr);
	expvar.Publish("counter", ctr);

	http.Handle("/go/", http.HandlerFunc(FileServer));
	http.Handle("/flags", http.HandlerFunc(FlagServer));
	http.Handle("/args", http.HandlerFunc(ArgServer));
	http.Handle("/go/hello", http.HandlerFunc(HelloServer));
	http.Handle("/chan", ChanCreate());
	http.Handle("/date", http.HandlerFunc(DateServer));
	err := http.ListenAndServe(":12345", nil);
	if err != nil {
		log.Crash("ListenAndServe: ", err)
	}
}
