package ginres

import (
	"strings"
	"unicode"

	"github.com/gin-gonic/gin"
)

// parseQuery convert query name into camelcase.
func ParseQuery(c *gin.Context, queries ...string) map[string]string {
	res := make(map[string]string, len(queries))
	for _, q := range queries {
		camelQ := camelString(q)
		if c.Query(q) != "" {
			res[camelQ] = c.Query(q)

			continue
		}
		snakeQ1 := snakeString(q, '-')
		if c.Query(snakeQ1) != "" {
			res[camelQ] = c.Query(snakeQ1)

			continue
		}
		snakeQ2 := snakeString(q, '_')
		if c.Query(snakeQ2) != "" {
			res[camelQ] = c.Query(snakeQ2)

			continue
		}
		res[camelQ] = ""
	}

	return res
}

func snakeString(s string, split byte) string {
	data := make([]byte, 0, len(s)*2)
	j := false
	num := len(s)
	for i := 0; i < num; i++ {
		d := s[i]
		if i > 0 && d >= 'A' && d <= 'Z' && j {
			data = append(data, split)
		}
		if d != split {
			j = true
		}
		data = append(data, d)
	}

	return strings.ToLower(string(data[:]))
}

func camelString(s string) string {
	data := make([]byte, 0, len(s))
	j := false
	k := false
	num := len(s) - 1
	for i := 0; i <= num; i++ {
		d := s[i]
		if k == false && d >= 'A' && d <= 'Z' {
			k = true
		}
		if d >= 'a' && d <= 'z' && (j || !k) {
			d = d - 32
			j = false
			k = true
		}
		if k && (d == '_' || d == '-') && num > i && s[i+1] >= 'a' && s[i+1] <= 'z' {
			j = true

			continue
		}
		data = append(data, d)
	}

	return Lcfirst(string(data[:]))
}

func Lcfirst(str string) string {
	for i, v := range str {
		return string(unicode.ToLower(v)) + str[i+1:]
	}

	return ""
}
