/*
 * Copyright (c) 2026, Chloe M.
 * Provided under the BSD-3 clause.
 *
 * Description:  Object manager
 * Author:       Chloe M.
 */

#ifndef _OB_OBJECT_H_
#define _OB_OBJECT_H_ 1

#include <stapi/status.h>
#include <stdef.h>

/* Maximum size of system object names */
#define OBJECT_NAMESZ 32

/* Slut tag for pool allocations */
#define OBJECT_POOL_TAG 'OB'

/*
 * Represents valid object types
 *
 * @OBJECT_TYPE_DIRECTORY: Object is directory
 */
typedef enum {
    OBJECT_TYPE_DIRECTORY
} OBJECT_TYPE;

/*
 * Represents a Slut Technology system object
 *
 * @Name:       Name of object
 * @RefCount:   Object reference count
 * @Type:       Object type
 * @Data:       Object data
 * @CacheNext:  Used when reclaiming object
 * @DirecNext:  Directory link
 */
typedef struct _ST_OBJECT {
    CHAR Name[OBJECT_NAMESZ];
    ULONG RefCount;
    OBJECT_TYPE Type;
    VOID *Data;
    struct _ST_OBJECT *CacheNext;
    struct _ST_OBJECT *DirecNext;
} ST_OBJECT;

/*
 * Represents a directory object containing one or more
 * objects.
 *
 * @First:      First entry in object directory
 * @Last:       Last entry in object directory
 * @EntryCount: Number of entries in directory
 */
typedef struct {
    ST_OBJECT *First;
    ST_OBJECT *Last;
    USIZE EntryCount;
} OBJECT_DIRECTORY;

/*
 * Create a new object directory
 *
 * @Name:   Name of object
 * @Result: Resulting object is written here
 */
ST_STATUS ObCreateDirectory(const CHAR *Name, ST_OBJECT **Result);

/*
 * Append an object to a directory
 *
 * @DirecParent: Parent of directory to append to
 * @Object:      Object to append to directory
 */
ST_STATUS ObAppendDirectory(ST_OBJECT *DirecParent, ST_OBJECT *Object);

/*
 * Allocate and create a new objec
 *
 * @Name:   Object name
 * @Type:   Object type
 * @Data:   Actual backing data
 * @Result: Result is written here
 */
ST_STATUS ObCreateObject(
    const CHAR *Name, OBJECT_TYPE Type,
    VOID *Data, ST_OBJECT **Result
);

/*
 * Initialize the object manager
 */
VOID ObInitManager(VOID);

/*
 * Look up an object from a parent directory
 *
 * @Parent: Parent directly to look up from
 * @Name:   Name of object to lookup
 * @Result: Result is written here
 */
ST_STATUS ObLookupFromTop(ST_OBJECT *Parent, const CHAR *Name, ST_OBJECT **Result);

/*
 * Reclaim an object after use, if its reference count is > 1, simply
 * bump it down. Once it hits zero, the object is returned to the cache.
 *
 * @Object: Object to reclaim
 */
VOID ObReclaimObject(ST_OBJECT *Object);

#endif  /* !_OB_OBJECT_H_ */
