package sqlite3

import (
	
	

	
)

// Error wraps an SQLite Error Code.
//
// https://sqlite.org/c3ref/errcode.html
type Error struct {
	msg  string
	sql  string
	code res_t
}

// Code returns the primary error code for this error.
//
// https://sqlite.org/rescode.html
func ( *Error) () ErrorCode {
	return ErrorCode(.code)
}

// ExtendedCode returns the extended error code for this error.
//
// https://sqlite.org/rescode.html
func ( *Error) () ExtendedErrorCode {
	return xErrorCode(.code)
}

// Error implements the error interface.
func ( *Error) () string {
	var  strings.Builder
	.WriteString(util.ErrorCodeString(uint32(.code)))

	if .msg != "" {
		.WriteString(": ")
		.WriteString(.msg)
	}

	return .String()
}

// Is tests whether this error matches a given [ErrorCode] or [ExtendedErrorCode].
//
// It makes it possible to do:
//
//	if errors.Is(err, sqlite3.BUSY) {
//		// ... handle BUSY
//	}
func ( *Error) ( error) bool {
	switch c := .(type) {
	case ErrorCode:
		return  == .Code()
	case ExtendedErrorCode:
		return  == .ExtendedCode()
	}
	return false
}

// As converts this error to an [ErrorCode] or [ExtendedErrorCode].
func ( *Error) ( any) bool {
	switch c := .(type) {
	case *ErrorCode:
		* = .Code()
		return true
	case *ExtendedErrorCode:
		* = .ExtendedCode()
		return true
	}
	return false
}

// Temporary returns true for [BUSY] errors.
func ( *Error) () bool {
	return .Code() == BUSY || .Code() == INTERRUPT
}

// Timeout returns true for [BUSY_TIMEOUT] errors.
func ( *Error) () bool {
	return .ExtendedCode() == BUSY_TIMEOUT
}

// SQL returns the SQL starting at the token that triggered a syntax error.
func ( *Error) () string {
	return .sql
}

// Error implements the error interface.
func ( ErrorCode) () string {
	return util.ErrorCodeString(uint32())
}

// Temporary returns true for [BUSY] errors.
func ( ErrorCode) () bool {
	return  == BUSY ||  == INTERRUPT
}

// ExtendedCode returns the extended error code for this error.
func ( ErrorCode) () ExtendedErrorCode {
	return xErrorCode()
}

// Error implements the error interface.
func ( ExtendedErrorCode) () string {
	return util.ErrorCodeString(uint32())
}

// Is tests whether this error matches a given [ErrorCode].
func ( ExtendedErrorCode) ( error) bool {
	,  := .(ErrorCode)
	return  &&  == ErrorCode()
}

// As converts this error to an [ErrorCode].
func ( ExtendedErrorCode) ( any) bool {
	,  := .(*ErrorCode)
	if  {
		* = ErrorCode()
	}
	return 
}

// Temporary returns true for [BUSY] errors.
func ( ExtendedErrorCode) () bool {
	return ErrorCode() == BUSY || ErrorCode() == INTERRUPT
}

// Timeout returns true for [BUSY_TIMEOUT] errors.
func ( ExtendedErrorCode) () bool {
	return  == BUSY_TIMEOUT
}

// Code returns the primary error code for this error.
func ( ExtendedErrorCode) () ErrorCode {
	return ErrorCode()
}

func errorCode( error,  ErrorCode) ( string,  res_t) {
	switch code := .(type) {
	case nil:
		return "", _OK
	case ErrorCode:
		return "", res_t()
	case xErrorCode:
		return "", res_t()
	case *Error:
		return .msg, res_t(.code)
	}

	var  ErrorCode
	var  xErrorCode
	switch {
	case errors.As(, &):
		 = res_t()
	case errors.As(, &):
		 = res_t()
	default:
		 = res_t()
	}
	return .Error(), 
}