/*------------------------------------------------------------------------------
 *
 * Copyright (c) 2011-2025, EURid vzw. All rights reserved.
 * The YADIFA TM software product is provided under the BSD 3-clause license:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *        * Redistributions of source code must retain the above copyright
 *          notice, this list of conditions and the following disclaimer.
 *        * Redistributions in binary form must reproduce the above copyright
 *          notice, this list of conditions and the following disclaimer in the
 *          documentation and/or other materials provided with the distribution.
 *        * Neither the name of EURid nor the names of its contributors may be
 *          used to endorse or promote products derived from this software
 *          without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *----------------------------------------------------------------------------*/

#pragma once

#include <dnscore/sys_types.h>

/**
 * For backward compatibility
 *
 * @param path
 */

void journal_set_xfr_path(const char *path);

/**
 * For backward compatibility
 *
 * @return
 */

const char *journal_get_xfr_path();

/**
 * The database does not know zone types. The only one that does is the server.
 * So it makes sense to provide it a way to chose where the DB will store journals.
 * This is especially important with the new primary/secondary journal separation
 *
 * The default provider returns something based on the XFR path (journal_set_xfr_path)
 *
 */

#define ZDB_ZONE_PATH_PROVIDER_ZONE_PATH   1   // want the full path of the directory for the zone
#define ZDB_ZONE_PATH_PROVIDER_ZONE_FILE   2   // want the full path of the file for the zone
#define ZDB_ZONE_PATH_PROVIDER_AXFR_PATH   3   // want the full path of the directory for the image of the zone (AXFR)
#define ZDB_ZONE_PATH_PROVIDER_AXFR_FILE   4   // want the full path of the directory for the image of the zone (AXFR)
#define ZDB_ZONE_PATH_PROVIDER_IXFR_PATH   5   // want the full path of the file for the incremental of the zone (IXFR/journal)
#define ZDB_ZONE_PATH_PROVIDER_IXFR_FILE   6   // want the full path of the file for the incremental of the zone (IXFR/journal)
#define ZDB_ZONE_PATH_PROVIDER_DNSKEY_PATH 7   // want the full path containing the DNSKEY keypairs for the zone (smart signing, key management)
#define ZDB_ZONE_PATH_PROVIDER_RNDSUFFIX   64  // appends a suffix to the file name (.SUFFIX), useful for temporary files/files being build
#define ZDB_ZONE_PATH_PROVIDER_MKDIR       128 // create the path before returning

typedef ya_result zdb_zone_path_provider_callback(const uint8_t *domain_fqdn, char *path_buffer, uint32_t path_buffer_size, uint32_t flags);

/**
 * Sets the provider.
 *
 * Note that the provider should return the length of the strings it returns.
 *
 * @param provider the provider or NULL to reset to the default one.
 */

void                             zdb_zone_path_set_provider(zdb_zone_path_provider_callback *provider);
zdb_zone_path_provider_callback *zdb_zone_path_get_provider();

struct zdb_zone_path_provider_buffer
{
    void    *ptr;
    uint32_t size;
};

typedef struct zdb_zone_path_provider_buffer zdb_zone_path_provider_buffer;

union zdb_zone_info_provider_data
{
    bool                          _bool;
    uint8_t                       _u8;
    uint16_t                      _u16;
    uint32_t                      _u32;
    uint64_t                      _u64;
    ya_result                     _result;
    void                         *_ptr;
    zdb_zone_path_provider_buffer _buffer;
};

typedef union zdb_zone_info_provider_data zdb_zone_info_provider_data;

/**
 * Zone info should be renamed into zone ctrl (not to be mixed with the server ctrl)
 * The zone ctrl may become a superset of the path provider
 * The zdb_zone_path_provider_data could become a generic high-level type
 */

typedef ya_result zdb_zone_info_provider_callback(const uint8_t *origin, zdb_zone_info_provider_data *data, uint32_t flags);

#define ZDB_ZONE_INFO_PROVIDER_STORED_SERIAL     0x100 // u32
#define ZDB_ZONE_INFO_PROVIDER_JOURNAL_SIZE_MAX  0x101 // u32
#define ZDB_ZONE_INFO_PROVIDER_ZONE_TYPE         0x102 // uint8_t (ZT_PRIMARY, ZT_SECONDARY, ...)

#define ZDB_ZONE_INFO_PROVIDER_STORE_TRIGGER     0x10000 // NULL, enqueues the storage of the zone
#define ZDB_ZONE_INFO_PROVIDER_STORE_NOW         0x10001 // ?, stores the zone now, in this thread
#define ZDB_ZONE_INFO_PROVIDER_STORE_IN_PROGRESS 0x10002 // ?, stores the zone now, in this thread

void                             zdb_zone_info_set_provider(zdb_zone_info_provider_callback *data);
zdb_zone_info_provider_callback *zdb_zone_info_get_provider();

ya_result                        zdb_zone_info_get_stored_serial(const uint8_t *origin, uint32_t *serial);

ya_result                        zdb_zone_info_get_zone_max_journal_size(const uint8_t *origin, uint32_t *size);

ya_result                        zdb_zone_info_get_zone_type(const uint8_t *origin, uint8_t *zt);

ya_result                        zdb_zone_info_store_locked_zone(const uint8_t *origin);

ya_result                        zdb_zone_info_background_store_zone(const uint8_t *origin);

/**
 *
 * Should not be used anymore.
 *
 * @param origin
 * @param minimum_serial
 * @return
 */

ya_result zdb_zone_info_background_store_zone_and_wait_for_serial(const uint8_t *origin, uint32_t minimum_serial);

ya_result zdb_zone_info_background_store_in_progress(const uint8_t *origin);

/** @} */
