package main

import "log"
import "sync"
import "path"
import "net/http"
import "crypto/tls"
import "html/template"
import "hnakra/service"

type Post struct {
	Author, Content string
	Next *Post
}

type Board struct {
	root     string
	mount    *service.HTTP
	mux      *http.ServeMux
	template *template.Template

	postsMutex sync.RWMutex
	posts *Post
}

func main () {
	board := Board { root: "/board/" }
	board.mux   = http.NewServeMux()
	board.mount = &service.HTTP {
		Mount: service.Mount {
			Path:        board.root,
			Name:        "Board",
			Description: "A board where you can post things.",
			TLSConfig:    &tls.Config { InsecureSkipVerify: true },
		},
		Handler: board.mux,
	}
	handle := func (pattern string, handler func (http.ResponseWriter, *http.Request)) {
		board.mux.HandleFunc(pattern, handler)
	}
	handle(board.root, board.serveHome)
	handle(path.Join(board.root, "actionPost"), board.serveActionPost)
	board.template = template.Must(template.New("board").Parse(tem))

	err := board.mount.Run()
	if err != nil {
		log.Println("XXX", err)
	}
}

func (board *Board) getPosts (max int) []*Post {
	board.postsMutex.RLock()
	defer board.postsMutex.RUnlock()
	
	posts := make([]*Post, max)
	count := 0
	current := board.posts
	for current != nil && count < max {
		posts[count] = current
		count ++
		current = current.Next
	}
	return posts[:count]
}

func (board *Board) serveHome (res http.ResponseWriter, req *http.Request) {
	if req.URL.Path != board.root {
		http.NotFoundHandler().ServeHTTP(res, req)
		return
	}
	res.Header().Add("content-type", "text/html")
	res.WriteHeader(http.StatusOK)
	board.template.ExecuteTemplate(res, "pageHome", board.getPosts(16))
}

func (board *Board) serveActionPost (res http.ResponseWriter, req *http.Request) {
	if req.Method != "POST" {
		res.Header().Add("content-type", "text/plain")
		res.WriteHeader(http.StatusMethodNotAllowed)
		res.Write([]byte("Method not allowed"))
		return
	}
	
	defer http.Redirect(res, req, board.root, http.StatusSeeOther)

	req.ParseForm()
	author  := req.PostFormValue("author")
	content := req.PostFormValue("content")
	
	board.posts = &Post {
		Author:  author,
		Content: content,
		Next:    board.posts,
	}
}
