package main

import (
		"net/http"
		"log"
		"sync"
		"regexp"
		"html/template"
)

type Page struct {
	tpl *template.Template
	Title string
	Name string
}

var (
    regexen = make(map[string]*regexp.Regexp)
    relock  sync.Mutex
	address = "127.0.0.1:8001"
)

var paths = map[string]string {
	"home": "home.tpl",
	"terms": "terms.tpl",
}

var pages = map[string]Page {
	"home": cache("home", "Home"),
	"terms": cache("terms", "Terms and Conditions"),
}

func cache(name string, title string) Page {
	var p = []string{"master.tpl", paths[name]}
	tpl := template.Must(template.ParseFiles(p...))
	return Page{tpl: tpl,
				Title: title,
				Name: name,
				}
}

func (page Page) Render(w http.ResponseWriter) {
	err := page.tpl.Execute(w, page)
	if err != nil {
		log.Print(err)
	}
}

func match(path, pattern string, args *[]string) bool {
	relock.Lock()
	defer relock.Unlock()
	regex := regexen[pattern]
	if regex == nil {
		regex = regexp.MustCompile("^" + pattern + "$")
		regexen[pattern] = regex
	}
	matches := regex.FindStringSubmatch(path)
	if len(matches) <= 0 {
		return false
	}
	*args = matches[1:]
	return true
}

func route(w http.ResponseWriter, r *http.Request) {
    var page Page
	var args []string

    p := r.URL.Path
    switch {
    case r.Method == "GET" && match(p, "/", &args):
        page = pages[ "home" ]
    case match(p, "/terms", &args):
        page = pages[ "terms" ]
    default:
        http.NotFound(w, r)
        return
    }

    page.Render(w)
}

func main() {
	http.HandleFunc("/", route)
	log.Fatal(http.ListenAndServe(address, nil))
}