package sql3util

import (
	
	
	
)

// NamedArg splits an named arg into a key and value,
// around an equals sign.
// Spaces are trimmed around both key and value.
func ( string) (,  string) {
	, , _ = strings.Cut(, "=")
	 = strings.TrimSpace()
	 = strings.TrimSpace()
	return
}

// Unquote unquotes a string.
//
// https://sqlite.org/lang_keywords.html
func ( string) string {
	if len() < 2 {
		return 
	}
	 := [0]
	 := [len()-1]
	 := [1 : len()-1]
	if  == '[' &&  == ']' {
		return 
	}
	if  !=  {
		return 
	}
	var ,  string
	switch  {
	default:
		return 
	case '`':
		,  = "``", "`"
	case '"':
		,  = `""`, `"`
	case '\'':
		,  = `''`, `'`
	}
	return strings.ReplaceAll(, , )
}

// ParseBool parses a boolean.
//
// https://sqlite.org/pragma.html#syntax
func ( string) (,  bool) {
	if len() == 0 {
		return false, false
	}
	if [0] == '0' {
		return false, true
	}
	if '1' <= [0] && [0] <= '9' {
		return true, true
	}
	switch strings.ToLower() {
	case "true", "yes", "on":
		return true, true
	case "false", "no", "off":
		return false, true
	}
	return false, false
}

// ParseFloat parses a decimal floating point number.
func ( string) ( float64,  bool) {
	if strings.TrimLeft(, "+-.0123456789Ee") != "" {
		return
	}
	,  := strconv.ParseFloat(, 64)
	return ,  == nil
}

// ParseTimeShift parses a time shift modifier,
// also the output of timediff.
//
// https://sqlite.org/lang_datefunc.html
func ( string) (, ,  int,  time.Duration,  bool) {
	// Sign part: ±
	 := strings.HasPrefix(, "-")
	 :=  || strings.HasPrefix(, "+")
	if  {
		 = [1:]
	}

	if  = len() >= 5; ! {
		return // !ok
	}

	defer func() {
		if  {
			 = -
			 = -
			 = -
			 = -
		}
	}()

	// Date part: YYYY-MM-DD
	if [4] == '-' {
		if  =  && len() >= 10 && [7] == '-'; ! {
			return // !ok
		}
		if ,  = parseInt([0:4], 0); ! {
			return // !ok
		}
		if ,  = parseInt([5:7], 12); ! {
			return // !ok
		}
		if ,  = parseInt([8:10], 31); ! {
			return // !ok
		}
		if len() == 10 {
			return
		}
		if  = [10] == ' '; ! {
			return // !ok
		}
		 = [11:]
	}

	// Time part: HH:MM
	if  = len() >= 5 && [2] == ':'; ! {
		return // !ok
	}

	var ,  int
	if ,  = parseInt([0:2], 24); ! {
		return
	}
	if ,  = parseInt([3:5], 60); ! {
		return
	}
	 = time.Duration()*time.Hour + time.Duration()*time.Minute

	if len() == 5 {
		return
	}
	if  = len() >= 8 && [5] == ':'; ! {
		return // !ok
	}

	// Seconds part: HH:MM:SS
	var  int
	if ,  = parseInt([6:8], 60); ! {
		return
	}
	 += time.Duration() * time.Second

	if len() == 8 {
		return
	}
	if  = len() >= 10 && [8] == '.'; ! {
		return // !ok
	}
	 = [9:]

	// Nanosecond part: HH:MM:SS.SSS
	var  int
	if ,  = parseInt([0:min(9, len())], 0); ! {
		return
	}
	for  := len();  < 9; ++ {
		 *= 10
	}
	 += time.Duration()

	// Subnanosecond part.
	if len() > 9 {
		_,  = parseInt([9:], 0)
	}
	return
}

func parseInt( string,  int) ( int,  bool) {
	for ,  := range []byte() {
		 -= '0'
		if  > 9 {
			return
		}
		 = *10 + int()
	}
	return ,  == 0 ||  < 
}