package sqlite3

import (
	
	
	

	
)

var (
	// +checklocks:extRegistryMtx
	extRegistry    []func(*Conn) error
	extRegistryMtx sync.RWMutex
)

// AutoExtension causes the entryPoint function to be invoked
// for each new database connection that is created.
//
// https://sqlite.org/c3ref/auto_extension.html
func ( func(*Conn) error) {
	extRegistryMtx.Lock()
	extRegistry = append(extRegistry, )
	extRegistryMtx.Unlock()
}

func initExtensions( *Conn) error {
	.base64()
	extRegistryMtx.RLock()
	defer extRegistryMtx.RUnlock()
	for ,  := range extRegistry {
		if  := ();  != nil {
			return 
		}
	}
	return nil
}

func ( *Conn) () error {
	return .CreateFunction("base64", 1, DETERMINISTIC, func( Context,  ...Value) {
		switch  := [0]; .Type() {
		case NULL:

		case BLOB:
			 := .RawBlob()
			 := base64.StdEncoding
			 := int64(.EncodedLen(len()))
			if  > _MAX_LENGTH {
				.ResultError(TOOBIG)
				return
			}
			 := .wrp.New()
			if  > 0 {
				.Encode(.wrp.Bytes(, ), )
			}
			.c.wrp.Xsqlite3_result_text_go(int32(.handle), int32(), )

		case TEXT:
			 := .RawText()
			 = bytes.Trim(, " \t\n\v\f\r")
			 = bytes.TrimRight(, "=")
			 := base64.RawStdEncoding
			 := int64(.DecodedLen(len()))
			if  > _MAX_LENGTH {
				.ResultError(TOOBIG)
				return
			}
			 := .wrp.New()
			if  > 0 {
				,  := .Decode(.wrp.Bytes(, ), )
				 = int64()
			}
			.c.wrp.Xsqlite3_result_blob_go(int32(.handle), int32(), )

		default:
			.ResultError(errutil.ErrorString("base64: accepts only blob or text"))
		}
	})
}

// ExtensionLibrary represents a dynamically linked SQLite extension.
type ExtensionLibrary interface {
	Xsqlite3_extension_init(db, _, _ int32) int32
}

// ExtensionInfo returns values needed to load a dynamically linked SQLite extension.
type ExtensionInfo func() (memorySize, memoryAlignment, tableSize, tableAlignment int64)

type extEnv struct {
	*env
	memoryBase int32
	tableBase  int32
}

func ( *extEnv) () *int32 { return &.memoryBase }
func ( *extEnv) () *int32  { return &.tableBase }

// ExtensionInit loads an SQLite extension library.
//
// https://sqlite.org/loadext.html
func [ any,  ExtensionLibrary]( *Conn,  func( ) ,  ExtensionInfo) error {
	, , ,  := ()

	var  int32
	if  > 0 {
		 = .wrp.Xaligned_alloc(int32(), int32())
		if  == 0 {
			panic(errutil.OOMErr)
		}
	}

	var  int
	if  > 0 {
		// Round up to the alignment.
		 := int() - 1
		 := .wrp.X__indirect_function_table()
		 = (len(*) + ) &^ 
		if  :=  + int() - len(*);  > 0 {
			* = append(*, make([]any, )...)
		}
	}

	 := &extEnv{
		env:        &env{.wrp},
		memoryBase: ,
		tableBase:  int32(),
	}

	 := (any().())
	if ,  := any().(interface{ () });  {
		.()
	}
	if ,  := any().(interface{ () });  {
		.()
	}
	 := .Xsqlite3_extension_init(int32(.handle), 0, 0)
	return .error(res_t())
}