package sqlite3

// Backup is an handle to an ongoing online backup operation.
//
// https://sqlite.org/c3ref/backup.html
type Backup struct {
	c      *Conn
	handle ptr_t
	otherc ptr_t
}

// Backup backs up srcDB on the src connection to the "main" database in dstURI.
//
// Backup opens the SQLite database file dstURI,
// and blocks until the entire backup is complete.
// Use [Conn.BackupInit] for incremental backup.
//
// https://sqlite.org/backup.html
func ( *Conn) (,  string) error {
	,  := .BackupInit(, )
	if  != nil {
		return 
	}
	defer .Close()
	_,  = .Step(-1)
	return 
}

// Restore restores dstDB on the dst connection from the "main" database in srcURI.
//
// Restore opens the SQLite database file srcURI,
// and blocks until the entire restore is complete.
//
// https://sqlite.org/backup.html
func ( *Conn) (,  string) error {
	,  := .openDB(, OPEN_READONLY|OPEN_URI)
	if  != nil {
		return 
	}
	,  := .backupInit(.handle, , , "main")
	if  != nil {
		return 
	}
	defer .Close()
	_,  = .Step(-1)
	return 
}

// BackupInit initializes a backup operation to copy the content of one database into another.
//
// BackupInit opens the SQLite database file dstURI,
// then initializes a backup that copies the contents of srcDB on the src connection
// to the "main" database in dstURI.
//
// https://sqlite.org/c3ref/backup_finish.html#sqlite3backupinit
func ( *Conn) (,  string) (*Backup, error) {
	,  := .openDB(, OPEN_READWRITE|OPEN_CREATE|OPEN_URI)
	if  != nil {
		return nil, 
	}
	return .backupInit(, "main", .handle, )
}

func ( *Conn) ( ptr_t,  string,  ptr_t,  string) (*Backup, error) {
	defer .arena.mark()()
	 := .arena.string()
	 := .arena.string()

	 := 
	if .handle ==  {
		 = 
	}

	 := ptr_t(.call("sqlite3_backup_init",
		stk_t(), stk_t(),
		stk_t(), stk_t()))
	if  == 0 {
		defer .closeDB()
		 := res_t(.call("sqlite3_errcode", stk_t()))
		return nil, .sqlite.error(, )
	}

	return &Backup{
		c:      ,
		otherc: ,
		handle: ,
	}, nil
}

// Close finishes a backup operation.
//
// It is safe to close a nil, zero or closed Backup.
//
// https://sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish
func ( *Backup) () error {
	if  == nil || .handle == 0 {
		return nil
	}

	 := res_t(.c.call("sqlite3_backup_finish", stk_t(.handle)))
	.c.closeDB(.otherc)
	.handle = 0
	return .c.error()
}

// Step copies up to nPage pages between the source and destination databases.
// If nPage is negative, all remaining source pages are copied.
//
// https://sqlite.org/c3ref/backup_finish.html#sqlite3backupstep
func ( *Backup) ( int) ( bool,  error) {
	 := res_t(.c.call("sqlite3_backup_step", stk_t(.handle), stk_t()))
	if  == _DONE {
		return true, nil
	}
	return false, .c.error()
}

// Remaining returns the number of pages still to be backed up
// at the conclusion of the most recent [Backup.Step].
//
// https://sqlite.org/c3ref/backup_finish.html#sqlite3backupremaining
func ( *Backup) () int {
	 := int32(.c.call("sqlite3_backup_remaining", stk_t(.handle)))
	return int()
}

// PageCount returns the total number of pages in the source database
// at the conclusion of the most recent [Backup.Step].
//
// https://sqlite.org/c3ref/backup_finish.html#sqlite3backuppagecount
func ( *Backup) () int {
	 := int32(.c.call("sqlite3_backup_pagecount", stk_t(.handle)))
	return int()
}