package bond

import (
	"strings"
	//"fmt"
	//"path"
)

// The type implements path routing for requests.
type PathRouter struct {
	pathMap map[string] Handler
	def Handler
}

// Returns new empty PathRouter.
func Path() *PathRouter {
	ret := &PathRouter{}
	ret.pathMap = map[string] Handler{}
	return ret
}

// Define new handler for the specified path.
// The defined path must not contain slashes and will panic otherwise.
func (router *PathRouter) Case(pth string, handler Handler) *PathRouter {
	_, dup := router.pathMap[pth]
	if dup {
		panic(DupDefErr)
	}
	router.pathMap[pth] = handler
	return router
}

// Implementing the Handler.
func (router *PathRouter) Handle(c *Context) {
	pth := c.Path()
	var splits []string
	var name, rest string

	if len(pth)>0 && pth[0] == '/' { // Handling the root path.
		splits = strings.SplitN(pth, "/", 3)
		if len(splits) > 1 {
			name = splits[1]
		}
		if len(splits) > 2 {
			rest = splits[2]
		}
	} else { // Handling the relative path. (second or n-th call)
		splits = strings.SplitN(pth, "/", 2)
		if len(splits) > 0 {
			name = splits[0]
		}
		if len(splits) > 1 {
			rest = splits[1]
		}
	}

	handler, ok := router.pathMap[name]
	if !ok {
		if router.def == nil {
			c.NotFound()
		} else {
			router.def.Handle(c)
		}
		return
	}

	c.RelUrl.Path = rest
	handler.Handle(c)
}

// The handler to fall to if no match for paths in the router.
func (router *PathRouter) Default(h Handler) *PathRouter {
	router.def = h
	return router
}