// 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 (
	"bufio";
	"exvar";
	"flag";
	"fmt";
	"http";
	"io";
	"log";
	"net";
	"os";
	"strconv";
)


// hello world, the web server
var helloRequests = exvar.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 exvar.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(io.ByteBuffer);
		io.Copy(req.Body, buf);
		body := string(buf.Data());
		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 = exvar.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(f, c);
	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(r, c);
	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);
	exvar.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)
	}
}

