package db

// CreateMailboxFolder records a custom folder's existence even before it holds any
// messages — idempotent (a folder a filter rule already delivered into can be
// explicitly created too, without erroring on the duplicate).
func (d *DB) CreateMailboxFolder(mailboxID int64, name string) error {
	_, err := d.Exec(`INSERT OR IGNORE INTO esrv_mailbox_folders (mailbox_id, name) VALUES (?, ?)`, mailboxID, name)
	return err
}

// DeleteMailboxFolder removes a custom folder's record. Callers are responsible for
// relocating any messages still in it first (see MoveAllMessagesInFolder) — this
// alone doesn't touch esrv_mailbox_messages.
func (d *DB) DeleteMailboxFolder(mailboxID int64, name string) error {
	_, err := d.Exec(`DELETE FROM esrv_mailbox_folders WHERE mailbox_id = ? AND name = ?`, mailboxID, name)
	return err
}

// ListMailboxFolders returns a mailbox's explicitly-created custom folders — combine
// with DistinctFoldersForMailbox (message-derived) for the full folder list, since a
// folder can exist via either path (or both).
func (d *DB) ListMailboxFolders(mailboxID int64) ([]string, error) {
	rows, err := d.Query(`SELECT name FROM esrv_mailbox_folders WHERE mailbox_id = ? ORDER BY name`, mailboxID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var out []string
	for rows.Next() {
		var name string
		if err := rows.Scan(&name); err != nil {
			return nil, err
		}
		out = append(out, name)
	}
	return out, rows.Err()
}

// MoveAllMessagesInFolder reassigns every message in one folder to another — used
// when deleting a custom folder, so its messages land in INBOX instead of becoming
// orphaned in a folder nothing lists anymore.
func (d *DB) MoveAllMessagesInFolder(mailboxID int64, from, to string) error {
	_, err := d.Exec(`UPDATE esrv_mailbox_messages SET folder = ? WHERE mailbox_id = ? AND folder = ?`, to, mailboxID, from)
	return err
}
