package goscaffold

import (
	"net/http"
	"regexp"
	"sort"
	"strconv"
	"strings"
)

var qParamRe = regexp.MustCompile("^q=([0-9\\.]+)$")

type acceptCriterion struct {
	major      string
	minor      string
	precedence float32
	origOrder  int
	match      string
}
type acceptCriteria []acceptCriterion

/*
SelectMediaType matches a set of candidate media types against the
Accept header in an HTTP request. It does this using the rules from
RFC2616 section 1.4.
If no Accept header is present, then the first choice in the
"choices" array is returned.
If multiple choices match, then we will take the first one specified
in the "Accept" header.
If there are no compatible media types, then an empty string
is returned.
Only the first "Accept" header on the request is considered.
*/
func SelectMediaType(req *http.Request, choices []string) string {
	hdr := req.Header.Get("Accept")
	if hdr == "" {
		if len(choices) >= 1 {
			return choices[0]
		}
		return ""
	}

	// Parse accept header and parse the criteria
	candidates := parseAcceptHeader(hdr)

	// For each choice, assign the best match (least wildcardy)
	matches := make(map[string]*acceptCriterion)
	for _, choice := range choices {
		for c := range candidates {
			crit := candidates[c]
			if crit.matches(choice) {
				if matches[choice] == nil ||
					matches[choice].level() < crit.level() {
					matches[choice] = &acceptCriterion{
						minor:      crit.minor,
						major:      crit.major,
						precedence: crit.precedence,
						origOrder:  crit.origOrder,
						match:      choice,
					}
				}
			}
		}
	}

	if len(matches) == 0 {
		return ""
	}

	// Sort the matches now by precedence level and original order
	var sortedMatches acceptCriteria
	for _, v := range matches {
		sortedMatches = append(sortedMatches, *v)
	}
	sortedMatches.sort()

	return sortedMatches[0].match
}

func parseAcceptHeader(hdr string) acceptCriteria {
	var ret acceptCriteria
	parts := strings.Split(hdr, ",")
	for i, part := range parts {
		candidate := parseAcceptPart(part, i)
		ret = append(ret, candidate)
	}
	return ret
}

/*
parseAcceptPart parses a single section of the header and extracts the
"q" parameter.
*/
func parseAcceptPart(part string, order int) acceptCriterion {
	params := strings.Split(part, ";")
	finalType := strings.TrimSpace(params[0])
	var precedence float32 = 1.0

	for _, param := range params[1:] {
		match := qParamRe.FindStringSubmatch(strings.TrimSpace(param))
		if match == nil {
			finalType += ";" + param
		} else {
			qVal, err := strconv.ParseFloat(match[1], 32)
			if err == nil {
				precedence = float32(qVal)
			}
		}
	}

	splitType := strings.SplitN(finalType, "/", 2)

	return acceptCriterion{
		major:      splitType[0],
		minor:      splitType[1],
		precedence: precedence,
		origOrder:  order,
	}
}

/*
matches matches a candidate media type with a criterion.
*/
func (a acceptCriterion) matches(t string) bool {
	st := strings.SplitN(t, "/", 2)

	if a.major != "*" && a.major != st[0] {
		return false
	}
	if a.minor != "*" && a.minor != st[1] {
		return false
	}
	return true
}
func (a acceptCriterion) level() int {
	if a.minor == "*" {
		if a.major == "*" {
			return 0
		}
		return 1
	}
	return 2
}

/*
sortCandidates sorts accept header candidates in order of:
1) Precedence (from the "q" parameter)
2) Original order in accept header
3) Stable sort otherwise
*/
func (c acceptCriteria) sort() {
	sort.Stable(c)
}

func (c acceptCriteria) Less(i, j int) bool {
	// Higher precedence goes first
	if c[i].precedence > c[j].precedence {
		return true
	}
	if c[i].precedence == c[j].precedence &&
		c[i].origOrder < c[j].origOrder {
		return true
	}
	return false
}

func (c acceptCriteria) Len() int {
	return len(c)
}

func (c acceptCriteria) Swap(i, j int) {
	tmp := c[i]
	c[i] = c[j]
	c[j] = tmp
}
