/*
 * Copyright 2025-2026 NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
 *
 * NOTICE TO LICENSEE:
 *
 * This source code and/or documentation ("Licensed Deliverables") are
 * subject to NVIDIA intellectual property rights under U.S. and
 * international Copyright laws.
 *
 * These Licensed Deliverables contained herein is PROPRIETARY and
 * CONFIDENTIAL to NVIDIA and is being provided under the terms and
 * conditions of a form of NVIDIA software license agreement by and
 * between NVIDIA and Licensee ("License Agreement") or electronically
 * accepted by Licensee.  Notwithstanding any terms or conditions to
 * the contrary in the License Agreement, reproduction or disclosure
 * of the Licensed Deliverables to any third party without the express
 * written consent of NVIDIA is prohibited.
 *
 * NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
 * LICENSE AGREEMENT, NVIDIA MAKES NO REPRESENTATION ABOUT THE
 * SUITABILITY OF THESE LICENSED DELIVERABLES FOR ANY PURPOSE.  IT IS
 * PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.
 * NVIDIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THESE LICENSED
 * DELIVERABLES, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
 * NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
 * NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
 * LICENSE AGREEMENT, IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY
 * SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 * OF THESE LICENSED DELIVERABLES.
 *
 * U.S. Government End Users.  These Licensed Deliverables are a
 * "commercial item" as that term is defined at 48 C.F.R. 2.101 (OCT
 * 1995), consisting of "commercial computer software" and "commercial
 * computer software documentation" as such terms are used in 48
 * C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Government
 * only as a commercial end item.  Consistent with 48 C.F.R.12.212 and
 * 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), all
 * U.S. Government End Users acquire the Licensed Deliverables with
 * only those rights set forth herein.
 *
 * Any use of the Licensed Deliverables in individual and commercial
 * software must include, in the user documentation and internal
 * comments to the code, the above Disclaimer and U.S. Government End
 * Users Notice.
 */

#ifndef CUEST_TYPES_H
#define CUEST_TYPES_H

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Enum containing all possible cuEST API return status codes.
 * @ingroup Enums
 *
 * Most API functions return one of these values to indicate error or success state.
 */
typedef enum {
    CUEST_STATUS_SUCCESS = 0,                   ///< Success: Operation completed with no error
    CUEST_STATUS_EXCEPTION = 1,                 ///< An exception was thrown during the operation
    CUEST_STATUS_NULL_POINTER = 2,              ///< One or more required input pointers were NULL
    CUEST_STATUS_INVALID_ARGUMENT = 3,          ///< One or more arguments were invalid (e.g., out-of-range, zero-length)
    CUEST_STATUS_INVALID_SIZE = 4,              ///< Input buffer/argument size did not match expected size
    CUEST_STATUS_INVALID_TYPE = 5,              ///< The specified cuEST type does not exist
    CUEST_STATUS_INVALID_PARAMETER = 6,         ///< The parameter being queried/set is invalid
    CUEST_STATUS_INVALID_ATTRIBUTE = 7,         ///< The attribute being queried is invalid
    CUEST_STATUS_INVALID_HANDLE = 8,            ///< The cuEST handle passed to the function is invalid
    CUEST_STATUS_UNKNOWN_ERROR = 9,             ///< Unspecified error: unknown or unexpected condition
    CUEST_STATUS_UNSUPPORTED_ARGUMENT = 10,     ///< One or more arguments are not supported by cuEST
    CUEST_STATUS_UNSUPPORTED_ARCHITECTURE = 11, ///< The device architecture is not supported by cuEST
    CUEST_STATUS_INVALID_PLAN = 12,             ///< One or more of the plans passed to the function were not in a usable state
    CUEST_STATUS_HOME_NOT_FOUND = 13            ///< The HOME environment variable is not set or empty, so the default JIT cache directory cannot be derived
} cuestStatus_t;

/**
 * @brief Opaque handle representing the cuEST library context.
 * @ingroup TypeDefs
 */
typedef void* cuestHandle_t;

/**
 * @brief Opaque handle representing a single atomic orbital (AO) Gaussian shell.
 *        See \c cuestAOShellAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestAOShell_t;

/**
 * @brief Opaque handle representing an atomic orbital (AO) basis set (group of AO shells).
 *        See \c cuestAOBasisAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestAOBasis_t;

/**
 * @brief Opaque handle representing a pair list of atomic orbitals.
 *        No attributes may be queried from this handle at this time.
 * @ingroup TypeDefs
 */
typedef void* cuestAOPairList_t;

/**
 * @brief Opaque handle representing a single ECP shell.
 *        See \c cuestECPShellAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestECPShell_t;

/**
 * @brief Opaque handle representing an ECP Atom (group of ECP shells).
 *        See \c cuestECPAtomAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestECPAtom_t;

/**
 * @brief Opaque handle for a one-electron integral computation plan (e.g., overlap integrals, kinetic integrals).
 *        No attributes may be queried from this handle at this time.
 * @ingroup TypeDefs
 */
typedef void* cuestOEIntPlan_t;

/**
 * @brief Opaque handle for an effective core potential (ECP) integral computation plan.
 *        See \c cuestECPIntPlanAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestECPIntPlan_t;

/**
 * @brief Opaque handle for a density-fitted integral computation plan (for DF/RI approaches).
 *        No attributes may be queried from this handle at this time.
 * @ingroup TypeDefs
 */
typedef void* cuestDFIntPlan_t;

/**
 * @brief Opaque handle representing the radial and angular grid points centered at a single atom
 * center.
 *        See \c cuestAtomGridAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestAtomGrid_t;

/**
 * @brief Opaque handle representing the DFT integration grid for a molecule.
 *        See \c cuestMolecularGridAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestMolecularGrid_t;

/**
 * @brief Opaque handle for an XC integral computation plan (e.g. XC potential and gradients).
 *        See \c cuestXCIntPlanAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestXCIntPlan_t;

/**
 * @brief Opaque handle for a PCM integral computation plan (e.g. PCM potential and gradients).
 *        See \c cuestPCMIntPlanAttributes_t for attributes that may be queried from this handle.
 * @ingroup TypeDefs
 */
typedef void* cuestPCMIntPlan_t;

/**
 * @brief Enum that provides unique identifiers for each of the opaque handles.
 * @ingroup Enums
 * 
 */
typedef enum {
    CUEST_HANDLE = 0,        ///< Alias for cuestHandle_t
    CUEST_AOSHELL = 1,       ///< Alias for cuestAOShell_t
    CUEST_AOBASIS = 2,       ///< Alias for cuestAOBasis_t
    CUEST_AOPAIRLIST = 3,    ///< Alias for cuestAOPairList_t
    CUEST_OEINTPLAN = 4,     ///< Alias for cuestOEIntPlan_t
    CUEST_DFINTPLAN = 5,     ///< Alias for cuestDFIntPlan_t
    CUEST_ATOMGRID = 6,      ///< Alias for cuestAtomGrid_t
    CUEST_MOLECULARGRID = 7, ///< Alias for cuestMolecularGrid_t
    CUEST_XCINTPLAN = 8,     ///< Alias for cuestXCIntPlan_t
    CUEST_PCMINTPLAN = 9,    ///< Alias for cuestPCMIntPlan_t
    CUEST_ECPSHELL = 10,     ///< Alias for cuestECPShell_t
    CUEST_ECPATOM = 11,      ///< Alias for cuestECPAtom_t
    CUEST_ECPINTPLAN = 12    ///< Alias for cuestECPIntPlan_t
} cuestType_t;

/**
 * @brief List of attributes that may be queried from a cuEST handle object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_HANDLE_NONE :       uint64_t
 */
typedef enum {
    CUEST_HANDLE_NONE = 0 ///< Reserved for future use.
} cuestHandleAttributes_t;

/**
 * @brief List of attributes that may be queried from an AO shell object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_AOSHELL_IS_PURE :       int32_t
 * - \c CUEST_AOSHELL_L :             uint64_t
 * - \c CUEST_AOSHELL_NUM_PRIMITIVE : uint64_t
 * - \c CUEST_AOSHELL_NUM_AO :        uint64_t
 * - \c CUEST_AOSHELL_NUM_PURE :      uint64_t
 * - \c CUEST_AOSHELL_NUM_CART :      uint64_t
 */
typedef enum {
    CUEST_AOSHELL_IS_PURE       = 0, ///< Whether shell uses pure (spherical) functions (nonzero if true)
    CUEST_AOSHELL_L             = 1, ///< Angular momentum quantum number (L)
    CUEST_AOSHELL_NUM_PRIMITIVE = 2, ///< Number of primitive Gaussians
    CUEST_AOSHELL_NUM_AO        = 3, ///< Number of basis functions (AOs, either pure or cartesian as set)
    CUEST_AOSHELL_NUM_PURE      = 4, ///< Number of pure (spherical) AOs
    CUEST_AOSHELL_NUM_CART      = 5  ///< Number of cartesian AOs
} cuestAOShellAttributes_t;

/**
 * @brief Enumerates properties that can be queried from an AO basis set object.
 * @ingroup Enums
 *
 * For each attribute, the expected type is:
 *
 * - \c CUEST_AOBASIS_IS_PURE :        int32_t
 * - \c CUEST_AOBASIS_IS_CART :        int32_t
 * - \c CUEST_AOBASIS_IS_MIXED :       int32_t
 * - \c CUEST_AOBASIS_NUM_ATOM :       uint64_t
 * - \c CUEST_AOBASIS_NUM_SHELL :      uint64_t
 * - \c CUEST_AOBASIS_NUM_AO :         uint64_t
 * - \c CUEST_AOBASIS_NUM_CART :       uint64_t
 * - \c CUEST_AOBASIS_NUM_PRIMITIVE :  uint64_t
 * - \c CUEST_AOBASIS_MAX_L :          uint64_t
 */
typedef enum {
    CUEST_AOBASIS_IS_PURE = 0,        ///< Nonzero if all shells are pure (spherical), zero otherwise
    CUEST_AOBASIS_IS_CART = 1,        ///< Nonzero if all shells are cartesian, zero otherwise
    CUEST_AOBASIS_IS_MIXED = 2,       ///< Nonzero if shells are mixed spherical/cartesian, zero otherwise
    CUEST_AOBASIS_NUM_ATOM = 3,       ///< Number of basis function centers
    CUEST_AOBASIS_NUM_SHELL = 4,      ///< Total number of AO shells
    CUEST_AOBASIS_NUM_AO = 5,         ///< Total number of basis functions (AOs)
    CUEST_AOBASIS_NUM_CART = 6,       ///< Total number of Cartesian basis functions
    CUEST_AOBASIS_NUM_PRIMITIVE = 7,  ///< Total number of Gaussian primitives
    CUEST_AOBASIS_MAX_L = 8           ///< Maximum angular momentum (L) among shells
} cuestAOBasisAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST AO pair list object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_AOPAIRLIST_NONE :       uint64_t
 */
typedef enum {
    CUEST_AOPAIRLIST_NONE = 0 ///< Reserved for future use.
} cuestAOPairListAttributes_t;

/**
 * @brief List of attributes that may be queried from an ECP shell object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_ECPSHELL_L :             uint64_t
 * - \c CUEST_ECPSHELL_NUM_PRIMITIVE : uint64_t
 */
typedef enum {
    CUEST_ECPSHELL_L             = 0, ///< Angular momentum quantum number (L)
    CUEST_ECPSHELL_NUM_PRIMITIVE = 1  ///< Number of primitives
} cuestECPShellAttributes_t;

/**
 * @brief List of attributes that may be queried from an ECP atom object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_ECPATOM_MAX_L :        uint64_t
 * - \c CUEST_ECPATOM_NUM_ELECTRON : uint64_t
 */
typedef enum {
    CUEST_ECPATOM_MAX_L            = 0, ///< Max angular momentum quantum number (L)
    CUEST_ECPATOM_NUM_ELECTRON     = 1  ///< Number of electrons
} cuestECPAtomAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST one-electron integral plan object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_OEINTPLAN_NONE :       uint64_t
 */
typedef enum {
    CUEST_OEINTPLAN_NONE = 0 ///< Reserved for future use.
} cuestOEIntPlanAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST effective core potential (ECP) integral plan object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_ECPINTPLAN_NUM_ACTIVE_ATOM :       uint64_t
 * - \c CUEST_ECPINTPLAN_NUM_ELECTRON :          uint64_t
 * - \c CUEST_ECPINTPLAN_MAX_L :                 uint64_t
 * - \c CUEST_ECPINTPLAN_NUM_RADIAL_POINT :      uint64_t
 * - \c CUEST_ECPINTPLAN_NUM_SPHERICAL_POINT :   uint64_t
 * - \c CUEST_ECPINTPLAN_NUM_POINT :             uint64_t
 */
typedef enum {
    CUEST_ECPINTPLAN_NUM_ACTIVE_ATOM       = 0, ///< Number of ECP active atoms
    CUEST_ECPINTPLAN_NUM_ELECTRON          = 1, ///< Number of electrons modeled by ECPs
    CUEST_ECPINTPLAN_MAX_L                 = 2, ///< Max angular momentum in ECP basis
    CUEST_ECPINTPLAN_NUM_RADIAL_POINT      = 3, ///< Number of radial grid points
    CUEST_ECPINTPLAN_NUM_SPHERICAL_POINT   = 4, ///< Number of angular grid points
    CUEST_ECPINTPLAN_NUM_POINT             = 5  ///< Number of grid points
} cuestECPIntPlanAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST DF integral plan object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_DFINTPLAN_NONE :       uint64_t
 */
typedef enum {
    CUEST_DFINTPLAN_NONE = 0 ///< Reserved for future use.
} cuestDFIntPlanAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST atom grid object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_ATOMGRID_NUM_POINT :         uint64_t
 * - \c CUEST_ATOMGRID_NUM_RADIAL_POINT :  uint64_t
 * - \c CUEST_ATOMGRID_MAX_ANGULAR_POINT : uint64_t
 */
typedef enum {
    CUEST_ATOMGRID_NUM_POINT         = 0, ///< Total number of grid points
    CUEST_ATOMGRID_NUM_RADIAL_POINT  = 1, ///< Number of radial points
    CUEST_ATOMGRID_MAX_ANGULAR_POINT = 2  ///< Maximum number of angular points
} cuestAtomGridAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST molecular grid object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_MOLECULARGRID_NUM_ATOM :                uint64_t
 * - \c CUEST_MOLECULARGRID_NUM_POINT :               uint64_t
 * - \c CUEST_MOLECULARGRID_MAX_POINT :               uint64_t
 * - \c CUEST_MOLECULARGRID_NUM_RADIAL_POINT :        uint64_t
 * - \c CUEST_MOLECULARGRID_MAX_RADIAL_POINT :        uint64_t
 * - \c CUEST_MOLECULARGRID_MAX_ANGULAR_POINT :       uint64_t
 */
typedef enum {
    CUEST_MOLECULARGRID_NUM_ATOM          = 0, ///< Number of atom centers in the grid definition
    CUEST_MOLECULARGRID_NUM_POINT         = 1, ///< Total number of grid points
    CUEST_MOLECULARGRID_MAX_POINT         = 2, ///< Maximum number of points for any atom
    CUEST_MOLECULARGRID_NUM_RADIAL_POINT  = 3, ///< Total number of radial points
    CUEST_MOLECULARGRID_MAX_RADIAL_POINT  = 4, ///< Maximum number of radial points for any atom
    CUEST_MOLECULARGRID_MAX_ANGULAR_POINT = 5  ///< Maximum number of angular points for any radial point
} cuestMolecularGridAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST XC integral plan object.
 * @ingroup Enums
 *
 * Note that queries involving char* attributes return a pointer to a string that must be
 * freed by the caller, using C's native free(), after use.
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_XCINTPLAN_EXCHANGE_SCALE :         double
 * - \c CUEST_XCINTPLAN_LRC_EXCHANGE_SCALE :     double
 * - \c CUEST_XCINTPLAN_LRC_OMEGA :              double
 * - \c CUEST_XCINTPLAN_VV10_SCALE :             double
 * - \c CUEST_XCINTPLAN_VV10_C :                 double
 * - \c CUEST_XCINTPLAN_VV10_B :                 double
 * - \c CUEST_XCINTPLAN_IS_HYBRID :              int32_t
 * - \c CUEST_XCINTPLAN_IS_LRC_HYBRID :          int32_t
 * - \c CUEST_XCINTPLAN_IS_VV10 :                int32_t
 * - \c CUEST_XCINTPLAN_ENGINE_DESCRIPTION :     char*
 * - \c CUEST_XCINTPLAN_ENGINE_CITATION :        char*
 * - \c CUEST_XCINTPLAN_FUNCTIONAL_CITATION :    char*
 * - \c CUEST_XCINTPLAN_FUNCTIONAL_DESCRIPTION : char*
 */
typedef enum {
    CUEST_XCINTPLAN_EXCHANGE_SCALE = 0,          ///< Scaling factor for HF (exact) exchange
    CUEST_XCINTPLAN_LRC_EXCHANGE_SCALE = 1,      ///< Scaling factor for LRC HF exchange
    CUEST_XCINTPLAN_LRC_OMEGA = 2,               ///< Omega for LRC-containing functionals
    CUEST_XCINTPLAN_VV10_SCALE = 3,              ///< VV10 scaling factor for non-local correlation
    CUEST_XCINTPLAN_VV10_C = 4,                  ///< VV10 C factor
    CUEST_XCINTPLAN_VV10_B = 5,                  ///< VV10 b factor
    CUEST_XCINTPLAN_IS_HYBRID = 6,               ///< Is the functional hybrid (contains HF exchange)?
    CUEST_XCINTPLAN_IS_LRC_HYBRID = 7,           ///< Is the functional LRC (contains LRC exchange)?
    CUEST_XCINTPLAN_IS_VV10 = 8,                 ///< Does the functional contain non-local VV10 correlation?
    CUEST_XCINTPLAN_ENGINE_DESCRIPTION = 9,      ///< Description of the XC evaluation engine
    CUEST_XCINTPLAN_ENGINE_CITATION = 10,        ///< Citation(s) for the XC evaluation engine
    CUEST_XCINTPLAN_FUNCTIONAL_CITATION = 11,    ///< Citation(s) for the functional
    CUEST_XCINTPLAN_FUNCTIONAL_DESCRIPTION = 12  ///< Description of the functional
} cuestXCIntPlanAttributes_t;

/**
 * @brief List of attributes that may be queried from a cuEST PCM integral plan object.
 * @ingroup Enums
 *
 * For each attribute, the expected return type is given:
 *
 * - \c CUEST_PCMINTPLAN_NUM_POINT :        uint64_t
 * - \c CUEST_PCMINTPLAN_NUM_ACTIVE_POINT : uint64_t
 */
typedef enum {
    CUEST_PCMINTPLAN_NUM_POINT = 0,         ///< Total number of surface points.
    CUEST_PCMINTPLAN_NUM_ACTIVE_POINT = 1   ///< Total number of active surface points, i.e. those not screened out by the iSWIG switching function.
} cuestPCMIntPlanAttributes_t;


#ifdef __cplusplus
}
#endif

#endif /* CUEST_TYPES_H */

