/*
 * The internal definitions
 *
 * Copyright (C) 2009-2024, Joachim Metz <joachim.metz@gmail.com>
 *
 * Refer to AUTHORS for acknowledgements.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#if !defined( _LIBESEDB_INTERNAL_DEFINITIONS_H )
#define _LIBESEDB_INTERNAL_DEFINITIONS_H

#include <common.h>
#include <byte_stream.h>

#include "libesedb_libfcache.h"
#include "libesedb_libfdata.h"

#define LIBESEDB_ENDIAN_BIG						_BYTE_STREAM_ENDIAN_BIG
#define LIBESEDB_ENDIAN_LITTLE						_BYTE_STREAM_ENDIAN_LITTLE

/* Define HAVE_LOCAL_LIBESEDB for local use of libesedb
 */
#if !defined( HAVE_LOCAL_LIBESEDB )
#include <libesedb/definitions.h>

/* The definitions in <libesedb/definitions.h> are copied here
 * for local use of libesedb
 */
#else
#define LIBESEDB_VERSION						20240420

/* The version string
 */
#define LIBESEDB_VERSION_STRING						"20240420"

/* The access flags definitions
 * bit 1        set to 1 for read access
 * bit 2        set to 1 for write access
 * bit 3-8      not used
 */
enum LIBESEDB_ACCESS_FLAGS
{
	LIBESEDB_ACCESS_FLAG_READ					= 0x01,
/* Reserved: not supported yet */
	LIBESEDB_ACCESS_FLAG_WRITE					= 0x02
};

/* The file access macros
 */
#define LIBESEDB_OPEN_READ						( LIBESEDB_ACCESS_FLAG_READ )
/* Reserved: not supported yet */
#define LIBESEDB_OPEN_WRITE						( LIBESEDB_ACCESS_FLAG_WRITE )
/* Reserved: not supported yet */
#define LIBESEDB_OPEN_READ_WRITE					( LIBESEDB_ACCESS_FLAG_READ | LIBESEDB_ACCESS_FLAG_WRITE )

/* The file types
 */
enum LIBESEDB_FILE_TYPES
{
	LIBESEDB_FILE_TYPE_DATABASE					= 0,
	LIBESEDB_FILE_TYPE_STREAMING_FILE				= 1
};

/* The get columns flags
 */
enum LIBESEDB_GET_COLUMN_FLAGS
{
	LIBESEDB_GET_COLUMN_FLAG_IGNORE_TEMPLATE_TABLE			= 0x01
};

/* The column types
 */
enum LIBESEDB_COLUMN_TYPES
{
	LIBESEDB_COLUMN_TYPE_NULL					= 0,
	LIBESEDB_COLUMN_TYPE_BOOLEAN					= 1,
	LIBESEDB_COLUMN_TYPE_INTEGER_8BIT_UNSIGNED			= 2,
	LIBESEDB_COLUMN_TYPE_INTEGER_16BIT_SIGNED			= 3,
	LIBESEDB_COLUMN_TYPE_INTEGER_32BIT_SIGNED			= 4,
	LIBESEDB_COLUMN_TYPE_CURRENCY					= 5,
	LIBESEDB_COLUMN_TYPE_FLOAT_32BIT				= 6,
	LIBESEDB_COLUMN_TYPE_DOUBLE_64BIT				= 7,
	LIBESEDB_COLUMN_TYPE_DATE_TIME					= 8,
	LIBESEDB_COLUMN_TYPE_BINARY_DATA				= 9,
	LIBESEDB_COLUMN_TYPE_TEXT					= 10,
	LIBESEDB_COLUMN_TYPE_LARGE_BINARY_DATA				= 11,
	LIBESEDB_COLUMN_TYPE_LARGE_TEXT					= 12,
	LIBESEDB_COLUMN_TYPE_SUPER_LARGE_VALUE				= 13,
	LIBESEDB_COLUMN_TYPE_INTEGER_32BIT_UNSIGNED			= 14,
	LIBESEDB_COLUMN_TYPE_INTEGER_64BIT_SIGNED			= 15,
	LIBESEDB_COLUMN_TYPE_GUID					= 16,
	LIBESEDB_COLUMN_TYPE_INTEGER_16BIT_UNSIGNED			= 17
};

/* The value flags
 */
enum LIBESEDB_VALUE_FLAGS
{
	LIBESEDB_VALUE_FLAG_VARIABLE_SIZE				= 0x01,
	LIBESEDB_VALUE_FLAG_COMPRESSED					= 0x02,
	LIBESEDB_VALUE_FLAG_LONG_VALUE					= 0x04,
	LIBESEDB_VALUE_FLAG_MULTI_VALUE					= 0x08,
	LIBESEDB_VALUE_FLAG_0x10					= 0x10
};

#endif /* !defined( HAVE_LOCAL_LIBESEDB ) */

#define LIBESEDB_FORMAT_REVISION_NEW_RECORD_FORMAT			0x0b
#define LIBESEDB_FORMAT_REVISION_EXTENDED_PAGE_HEADER			0x11

/* The page flags
 */
enum LIBESEDB_PAGE_FLAGS
{
	LIBESEDB_PAGE_FLAG_IS_ROOT					= 0x00000001,
	LIBESEDB_PAGE_FLAG_IS_LEAF					= 0x00000002,
	LIBESEDB_PAGE_FLAG_IS_PARENT					= 0x00000004,
	LIBESEDB_PAGE_FLAG_IS_EMPTY					= 0x00000008,

	LIBESEDB_PAGE_FLAG_IS_SPACE_TREE				= 0x00000020,
	LIBESEDB_PAGE_FLAG_IS_INDEX					= 0x00000040,
	LIBESEDB_PAGE_FLAG_IS_LONG_VALUE				= 0x00000080,

	LIBESEDB_PAGE_FLAG_0x0400					= 0x00000400,
	LIBESEDB_PAGE_FLAG_0x0800					= 0x00000800,

	LIBESEDB_PAGE_FLAG_IS_NEW_RECORD_FORMAT				= 0x00002000,
	LIBESEDB_PAGE_FLAG_IS_SCRUBBED					= 0x00004000,
	LIBESEDB_PAGE_FLAG_0x8000					= 0x00008000,
	LIBESEDB_PAGE_FLAG_0x10000					= 0x00010000
};

/* The page tag flags
 */
enum LIBESEDB_PAGE_TAG_FLAGS
{
	LIBESEDB_PAGE_TAG_FLAG_0x01					= 0x01,
	LIBESEDB_PAGE_TAG_FLAG_IS_DEFUNCT				= 0x02,
	LIBESEDB_PAGE_TAG_FLAG_HAS_COMMON_KEY_SIZE			= 0x04
};

/* The catalog definitions types
 */
enum LIBESEDB_CATALOG_DEFINITION_TYPES
{
	LIBESEDB_CATALOG_DEFINITION_TYPE_TABLE				= 1,
	LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN				= 2,
	LIBESEDB_CATALOG_DEFINITION_TYPE_INDEX				= 3,
	LIBESEDB_CATALOG_DEFINITION_TYPE_LONG_VALUE			= 4,
	LIBESEDB_CATALOG_DEFINITION_TYPE_CALLBACK			= 5
};

/* Definitions of fixed FDP object identifiers
 */
#define LIBESEDB_FDP_OBJECT_IDENTIFIER_DATABASE				1
#define LIBESEDB_FDP_OBJECT_IDENTIFIER_CATALOG				2
#define LIBESEDB_FDP_OBJECT_IDENTIFIER_CATALOG_BACKUP			3

/* Definitions of fixed page numbers
 */
#define LIBESEDB_PAGE_NUMBER_DATABASE					1
#define LIBESEDB_PAGE_NUMBER_CATALOG					4
#define LIBESEDB_PAGE_NUMBER_CATALOG_BACKUP				24

/* Page key search related definitions
 */
enum LIBESEDB_PAGE_KEY_FLAGS
{
	LIBESEDB_PAGE_KEY_FLAG_REVERSED_KEY				= 0x01,

	LIBESEDB_PAGE_KEY_FLAG_TEST					= 0x80
};

/* The key type definitions
 */
enum LIBESEDB_KEY_TYPES
{
	LIBESEDB_KEY_TYPE_BRANCH					= (uint8_t) 'b',
	LIBESEDB_KEY_TYPE_INDEX_VALUE					= (uint8_t) 'I',
	LIBESEDB_KEY_TYPE_LEAF						= (uint8_t) 'l',
	LIBESEDB_KEY_TYPE_LONG_VALUE					= (uint8_t) 'L',
	LIBESEDB_KEY_TYPE_LONG_VALUE_SEGMENT				= (uint8_t) 'S'
};

/* The tagged data type format definitions
 */
enum LIBESEDB_TAGGED_DATA_TYPES_FORMATS
{
	LIBESEDB_TAGGED_DATA_TYPES_FORMAT_LINEAR,
	LIBESEDB_TAGGED_DATA_TYPES_FORMAT_INDEX,
};

/* The record flags
 */
enum LIBESEDB_RECORD_FLAGS
{
	LIBESEDB_RECORD_FLAG_IS_CORRUPTED				= 0x01,
};

/* The file attribute flags
 */
enum LIBESEDB_FILE_ATTRIBUTE_FLAGS
{
	LIBESEDB_FILE_ATTRIBUTE_FLAG_READ_ONLY				= 0x00000001,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_HIDDEN				= 0x00000002,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_SYSTEM				= 0x00000004,

	LIBESEDB_FILE_ATTRIBUTE_FLAG_DIRECTORY				= 0x00000010,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_ARCHIVE				= 0x00000020,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_DEVICE				= 0x00000040,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_NORMAL				= 0x00000080,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_TEMPORARY				= 0x00000100,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_SPARSE_FILE			= 0x00000200,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_REPARSE_POINT			= 0x00000400,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_COMPRESSED				= 0x00000800,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_OFFLINE				= 0x00001000,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_NOT_CONTENT_INDEXED		= 0x00002000,
	LIBESEDB_FILE_ATTRIBUTE_FLAG_ENCRYPTED				= 0x00004000,

	LIBESEDB_FILE_ATTRIBUTE_FLAG_VIRTUAL				= 0x00010000
};

/* Flag to indicate the page tree node is virtual
 */
#define LIBESEDB_PAGE_TREE_NODE_FLAG_IS_VIRTUAL				LIBFDATA_RANGE_FLAG_USER_DEFINED_1

/* The maximum number of cache entries definitions
 */
#define LIBESEDB_MAXIMUM_CACHE_ENTRIES_PAGES				( 8 * 1024 ) - 3
#define LIBESEDB_MAXIMUM_CACHE_ENTRIES_INDEX_VALUES			( 32 * 1024 ) - 3
#define LIBESEDB_MAXIMUM_CACHE_ENTRIES_LONG_VALUES			( 128 * 1024 ) - 3
#define LIBESEDB_MAXIMUM_CACHE_ENTRIES_LONG_VALUES_DATA			8
#define LIBESEDB_MAXIMUM_CACHE_ENTRIES_TABLE_VALUES			( 32 * 1024 ) - 3
#define LIBESEDB_MAXIMUM_CACHE_ENTRIES_TREE_VALUES			( 128 * 1024 ) - 3

#define LIBESEDB_VALUE_DATA_FLAG_HAS_TAG_DATA_TYPE_FLAGS		LIBFVALUE_VALUE_DATA_FLAG_USER_DEFINED_1

#define LIBESEDB_BLOCK_TREE_NUMBER_OF_SUB_NODES				256

#define LIBESEDB_MAXIMUM_NUMBER_OF_LEAF_PAGES				16 * 1024

#define LIBESEDB_MAXIMUM_INDEX_NODE_RECURSION_DEPTH			256

#endif /* !defined( _LIBESEDB_INTERNAL_DEFINITIONS_H ) */

