package restful

// Copyright 2013 Ernest Micklei. All rights reserved.
// Use of this source code is governed by a license
// that can be found in the LICENSE file.

import (
	"errors"
	"fmt"
	"net/http"
	"sort"
)

// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions)
// as specified by the JSR311 http://jsr311.java.net/nonav/releases/1.1/spec/spec.html.
// RouterJSR311 implements the Router interface.
// Concept of locators is not implemented.
type RouterJSR311 struct{}

// SelectRoute is part of the Router interface and returns the best match
// for the WebService and its Route for the given Request.
func (r RouterJSR311) SelectRoute(
	webServices []*WebService,
	httpRequest *http.Request) (selectedService *WebService, selectedRoute *Route, err error) {

	// Identify the root resource class (WebService)
	dispatcher, finalMatch, err := r.detectDispatcher(httpRequest.URL.Path, webServices)
	if err != nil {
		return nil, nil, NewError(http.StatusNotFound, "")
	}
	// Obtain the set of candidate methods (Routes)
	routes := r.selectRoutes(dispatcher, finalMatch)
	if len(routes) == 0 {
		return dispatcher, nil, NewError(http.StatusNotFound, "404: Page Not Found")
	}

	// Identify the method (Route) that will handle the request
	route, ok := r.detectRoute(routes, httpRequest)
	return dispatcher, route, ok
}

// ExtractParameters is used to obtain the path parameters from the route using the same matching
// engine as the JSR 311 router.
func (r RouterJSR311) ExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string {
	webServiceExpr := webService.pathExpr
	webServiceMatches := webServiceExpr.Matcher.FindStringSubmatch(urlPath)
	pathParameters := r.extractParams(webServiceExpr, webServiceMatches)
	routeExpr := route.pathExpr
	routeMatches := routeExpr.Matcher.FindStringSubmatch(webServiceMatches[len(webServiceMatches)-1])
	routeParams := r.extractParams(routeExpr, routeMatches)
	for key, value := range routeParams {
		pathParameters[key] = value
	}
	return pathParameters
}

func (RouterJSR311) extractParams(pathExpr *pathExpression, matches []string) map[string]string {
	params := map[string]string{}
	for i := 1; i < len(matches); i++ {
		if len(pathExpr.VarNames) >= i {
			params[pathExpr.VarNames[i-1]] = matches[i]
		}
	}
	return params
}

// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2
func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*Route, error) {
	ifOk := []Route{}
	for _, each := range routes {
		ok := true
		for _, fn := range each.If {
			if !fn(httpRequest) {
				ok = false
				break
			}
		}
		if ok {
			ifOk = append(ifOk, each)
		}
	}
	if len(ifOk) == 0 {
		if trace {
			traceLogger.Printf("no Route found (from %d) that passes conditional checks", len(routes))
		}
		return nil, NewError(http.StatusNotFound, "404: Not Found")
	}

	// http method
	methodOk := []Route{}
	for _, each := range ifOk {
		if httpRequest.Method == each.Method {
			methodOk = append(methodOk, each)
		}
	}
	if len(methodOk) == 0 {
		if trace {
			traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(routes), httpRequest.Method)
		}
		return nil, NewError(http.StatusMethodNotAllowed, "405: Method Not Allowed")
	}
	inputMediaOk := methodOk

	// content-type
	contentType := httpRequest.Header.Get(HEADER_ContentType)
	inputMediaOk = []Route{}
	for _, each := range methodOk {
		if each.matchesContentType(contentType) {
			inputMediaOk = append(inputMediaOk, each)
		}
	}
	if len(inputMediaOk) == 0 {
		if trace {
			traceLogger.Printf("no Route found (from %d) that matches HTTP Content-Type: %s\n", len(methodOk), contentType)
		}
		return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type")
	}

	// accept
	outputMediaOk := []Route{}
	accept := httpRequest.Header.Get(HEADER_Accept)
	if len(accept) == 0 {
		accept = "*/*"
	}
	for _, each := range inputMediaOk {
		if each.matchesAccept(accept) {
			outputMediaOk = append(outputMediaOk, each)
		}
	}
	if len(outputMediaOk) == 0 {
		if trace {
			traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(inputMediaOk), accept)
		}
		return nil, NewError(http.StatusNotAcceptable, "406: Not Acceptable")
	}
	// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
	return &outputMediaOk[0], nil
}

// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2
// n/m > n/* > */*
func (r RouterJSR311) bestMatchByMedia(routes []Route, contentType string, accept string) *Route {
	// TODO
	return &routes[0]
}

// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2  (step 2)
func (r RouterJSR311) selectRoutes(dispatcher *WebService, pathRemainder string) []Route {
	filtered := &sortableRouteCandidates{}
	for _, each := range dispatcher.Routes() {
		pathExpr := each.pathExpr
		matches := pathExpr.Matcher.FindStringSubmatch(pathRemainder)
		if matches != nil {
			lastMatch := matches[len(matches)-1]
			if len(lastMatch) == 0 || lastMatch == "/" { // do not include if value is neither empty nor ‘/’.
				filtered.candidates = append(filtered.candidates,
					routeCandidate{each, len(matches) - 1, pathExpr.LiteralCount, pathExpr.VarCount})
			}
		}
	}
	if len(filtered.candidates) == 0 {
		if trace {
			traceLogger.Printf("WebService on path %s has no routes that match URL path remainder:%s\n", dispatcher.rootPath, pathRemainder)
		}
		return []Route{}
	}
	sort.Sort(sort.Reverse(filtered))

	// select other routes from candidates whoes expression matches rmatch
	matchingRoutes := []Route{filtered.candidates[0].route}
	for c := 1; c < len(filtered.candidates); c++ {
		each := filtered.candidates[c]
		if each.route.pathExpr.Matcher.MatchString(pathRemainder) {
			matchingRoutes = append(matchingRoutes, each.route)
		}
	}
	return matchingRoutes
}

// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 1)
func (r RouterJSR311) detectDispatcher(requestPath string, dispatchers []*WebService) (*WebService, string, error) {
	filtered := &sortableDispatcherCandidates{}
	for _, each := range dispatchers {
		matches := each.pathExpr.Matcher.FindStringSubmatch(requestPath)
		if matches != nil {
			filtered.candidates = append(filtered.candidates,
				dispatcherCandidate{each, matches[len(matches)-1], len(matches), each.pathExpr.LiteralCount, each.pathExpr.VarCount})
		}
	}
	if len(filtered.candidates) == 0 {
		if trace {
			traceLogger.Printf("no WebService was found to match URL path:%s\n", requestPath)
		}
		return nil, "", errors.New("not found")
	}
	sort.Sort(sort.Reverse(filtered))
	return filtered.candidates[0].dispatcher, filtered.candidates[0].finalMatch, nil
}

// Types and functions to support the sorting of Routes

type routeCandidate struct {
	route           Route
	matchesCount    int // the number of capturing groups
	literalCount    int // the number of literal characters (means those not resulting from template variable substitution)
	nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^  /]+?)’)
}

func (r routeCandidate) expressionToMatch() string {
	return r.route.pathExpr.Source
}

func (r routeCandidate) String() string {
	return fmt.Sprintf("(m=%d,l=%d,n=%d)", r.matchesCount, r.literalCount, r.nonDefaultCount)
}

type sortableRouteCandidates struct {
	candidates []routeCandidate
}

func (rcs *sortableRouteCandidates) Len() int {
	return len(rcs.candidates)
}
func (rcs *sortableRouteCandidates) Swap(i, j int) {
	rcs.candidates[i], rcs.candidates[j] = rcs.candidates[j], rcs.candidates[i]
}
func (rcs *sortableRouteCandidates) Less(i, j int) bool {
	ci := rcs.candidates[i]
	cj := rcs.candidates[j]
	// primary key
	if ci.literalCount < cj.literalCount {
		return true
	}
	if ci.literalCount > cj.literalCount {
		return false
	}
	// secundary key
	if ci.matchesCount < cj.matchesCount {
		return true
	}
	if ci.matchesCount > cj.matchesCount {
		return false
	}
	// tertiary key
	if ci.nonDefaultCount < cj.nonDefaultCount {
		return true
	}
	if ci.nonDefaultCount > cj.nonDefaultCount {
		return false
	}
	// quaternary key ("source" is interpreted as Path)
	return ci.route.Path < cj.route.Path
}

// Types and functions to support the sorting of Dispatchers

type dispatcherCandidate struct {
	dispatcher      *WebService
	finalMatch      string
	matchesCount    int // the number of capturing groups
	literalCount    int // the number of literal characters (means those not resulting from template variable substitution)
	nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^  /]+?)’)
}
type sortableDispatcherCandidates struct {
	candidates []dispatcherCandidate
}

func (dc *sortableDispatcherCandidates) Len() int {
	return len(dc.candidates)
}
func (dc *sortableDispatcherCandidates) Swap(i, j int) {
	dc.candidates[i], dc.candidates[j] = dc.candidates[j], dc.candidates[i]
}
func (dc *sortableDispatcherCandidates) Less(i, j int) bool {
	ci := dc.candidates[i]
	cj := dc.candidates[j]
	// primary key
	if ci.matchesCount < cj.matchesCount {
		return true
	}
	if ci.matchesCount > cj.matchesCount {
		return false
	}
	// secundary key
	if ci.literalCount < cj.literalCount {
		return true
	}
	if ci.literalCount > cj.literalCount {
		return false
	}
	// tertiary key
	return ci.nonDefaultCount < cj.nonDefaultCount
}
