public namespace slang
{

public typedef int32_t Result;
public typedef uint64_t Size;
public typedef int64_t Int;
public typedef uint64_t UInt;

/*!
@brief Severity of a diagnostic generated by the compiler.
Values come from the enum below, with higher values representing more severe
conditions, and all values >= SLANG_SEVERITY_ERROR indicating compilation
failure.
*/
public enum SlangSeverity
{
    SLANG_SEVERITY_DISABLED = 0, /**< A message that is disabled, filtered out. */
    SLANG_SEVERITY_NOTE,         /**< An informative message. */
    SLANG_SEVERITY_WARNING,      /**< A warning, which indicates a possible proble. */
    SLANG_SEVERITY_ERROR,        /**< An error, indicating that compilation failed. */
    SLANG_SEVERITY_FATAL,        /**< An unrecoverable error, which forced compilation to abort. */
    SLANG_SEVERITY_INTERNAL,     /**< An internal error, indicating a logic error in the compiler. */
};

public enum SlangDiagnosticFlags
{
    SLANG_DIAGNOSTIC_FLAG_VERBOSE_PATHS = 0x01,
    SLANG_DIAGNOSTIC_FLAG_TREAT_WARNINGS_AS_ERRORS = 0x02
};

public enum SlangBindableResourceType
{
    SLANG_NON_BINDABLE = 0,
    SLANG_TEXTURE,
    SLANG_SAMPLER,
    SLANG_UNIFORM_BUFFER,
    SLANG_STORAGE_BUFFER,
};

public enum SlangCompileTarget
{
    SLANG_TARGET_UNKNOWN,
    SLANG_TARGET_NONE,
    SLANG_GLSL,
    SLANG_GLSL_VULKAN,          //< deprecated: just use `SLANG_GLSL`
    SLANG_GLSL_VULKAN_ONE_DESC, //< deprecated
    SLANG_HLSL,
    SLANG_SPIRV,
    SLANG_SPIRV_ASM,
    SLANG_DXBC,
    SLANG_DXBC_ASM,
    SLANG_DXIL,
    SLANG_DXIL_ASM,
    SLANG_C_SOURCE,              ///< The C language
    SLANG_CPP_SOURCE,            ///< C++ code for shader kernels.
    SLANG_CPP_PYTORCH_BINDING,
    SLANG_HOST_EXECUTABLE,       ///<  Standalone binary executable (for hosting CPU/OS)
    SLANG_SHADER_SHARED_LIBRARY, ///< A shared library/Dll for shader kernels (for hosting CPU/OS)
    SLANG_SHADER_HOST_CALLABLE,  ///< A CPU target that makes the compiled shader code available to be run immediately
    SLANG_CUDA_SOURCE,           ///< Cuda source
    SLANG_PTX,                   ///< PTX
    SLANG_OBJECT_CODE,           ///< Object code that can be used for later linking
    SLANG_HOST_CPP_SOURCE,       ///< C++ code for host library or executable.
    SLANG_HOST_HOST_CALLABLE,    ///<
    SLANG_CPP_HEADER,            ///< C++ header for shader kernels.
    SLANG_CUDA_HEADER,           ///< Cuda header
    SLANG_TARGET_COUNT_OF,
};

/* A "container format" describes the way that the outputs
for multiple files, entry points, targets, etc. should be
combined into a single artifact for output. */
public enum SlangContainerFormat
{
    /* Don't generate a container. */
    SLANG_CONTAINER_FORMAT_NONE,

    /* Generate a container in the `.slang-module` format,
    which includes reflection information, compiled kernels, etc. */
    SLANG_CONTAINER_FORMAT_SLANG_MODULE,
};

public enum SlangPassThrough : int
{
    SLANG_PASS_THROUGH_NONE,
    SLANG_PASS_THROUGH_FXC,
    SLANG_PASS_THROUGH_DXC,
    SLANG_PASS_THROUGH_GLSLANG,
    SLANG_PASS_THROUGH_SPIRV_DIS,
    SLANG_PASS_THROUGH_CLANG,         ///< Clang C/C++ compiler
    SLANG_PASS_THROUGH_VISUAL_STUDIO, ///< Visual studio C/C++ compiler
    SLANG_PASS_THROUGH_GCC,           ///< GCC C/C++ compiler
    SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C or C++ compiler, which is decided by the source type
    SLANG_PASS_THROUGH_NVRTC,         ///< NVRTC Cuda compiler
    SLANG_PASS_THROUGH_LLVM,          ///< LLVM 'compiler' - includes LLVM and Clang
    SLANG_PASS_THROUGH_SPIRV_OPT,
    SLANG_PASS_THROUGH_COUNT_OF,
};

/* Defines an archive type used to holds a 'file system' type structure. */
public enum SlangArchiveType : int
{
    SLANG_ARCHIVE_TYPE_UNDEFINED,
    SLANG_ARCHIVE_TYPE_ZIP,
    SLANG_ARCHIVE_TYPE_RIFF, ///< Riff container with no compression
    SLANG_ARCHIVE_TYPE_RIFF_DEFLATE,
    SLANG_ARCHIVE_TYPE_RIFF_LZ4,
    SLANG_ARCHIVE_TYPE_COUNT_OF,
};

/*!
Flags to control compilation behavior.
*/
public enum SlangCompileFlags
{
    /* Do as little mangling of names as possible, to try to preserve original names */
    SLANG_COMPILE_FLAG_NO_MANGLING = 1 << 3,

    /* Skip code generation step, just check the code and generate layout */
    SLANG_COMPILE_FLAG_NO_CODEGEN = 1 << 4,

    /* Obfuscate shader names on release products */
    SLANG_COMPILE_FLAG_OBFUSCATE = 1 << 5,

    /* Deprecated flags: kept around to allow existing applications to
    compile. Note that the relevant features will still be left in
    their default state. */
    SLANG_COMPILE_FLAG_NO_CHECKING = 0,
    SLANG_COMPILE_FLAG_SPLIT_MIXED_TYPES = 0,
};

/*!
@brief Flags to control code generation behavior of a compilation target */
public enum SlangTargetFlags
{
    None = 0,

    /* When compiling for a D3D Shader Model 5.1 or higher target, allocate
       distinct register spaces for parameter blocks.

       @deprecated This behavior is now enabled unconditionally.
    */
    SLANG_TARGET_FLAG_PARAMETER_BLOCKS_USE_REGISTER_SPACES = 1 << 4,

    /* When set, will generate target code that contains all entrypoints defined
       in the input source or specified via the `spAddEntryPoint` function in a
       single output module (library/source file).
    */
    SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM = 1 << 8,

    /* When set, will dump out the IR between intermediate compilation steps.*/
    SLANG_TARGET_FLAG_DUMP_IR = 1 << 9,

    /* When set, will generate SPIRV directly instead of going through glslang. */
    SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY = 1 << 10,
};

/*!
@brief Options to control floating-point precision guarantees for a target.
*/
public enum SlangFloatingPointMode
{
    SLANG_FLOATING_POINT_MODE_DEFAULT = 0,
    SLANG_FLOATING_POINT_MODE_FAST,
    SLANG_FLOATING_POINT_MODE_PRECISE,
};

/*!
@brief Options to control emission of `#line` directives
*/
public enum SlangLineDirectiveMode
{
    SLANG_LINE_DIRECTIVE_MODE_DEFAULT = 0, /**< Default behavior: pick behavior base on target. */
    SLANG_LINE_DIRECTIVE_MODE_NONE,        /**< Don't emit line directives at all. */
    SLANG_LINE_DIRECTIVE_MODE_STANDARD,    /**< Emit standard C-style `#line` directives. */
    SLANG_LINE_DIRECTIVE_MODE_GLSL,        /**< Emit GLSL-style directives with file *number* instead of name */
};

public enum SlangSourceLanguage : int
{
    SLANG_SOURCE_LANGUAGE_UNKNOWN,
    SLANG_SOURCE_LANGUAGE_SLANG,
    SLANG_SOURCE_LANGUAGE_HLSL,
    SLANG_SOURCE_LANGUAGE_GLSL,
    SLANG_SOURCE_LANGUAGE_C,
    SLANG_SOURCE_LANGUAGE_CPP,
    SLANG_SOURCE_LANGUAGE_CUDA,
    SLANG_SOURCE_LANGUAGE_COUNT_OF,
};

public enum SlangProfileID
{
    SLANG_PROFILE_UNKNOWN,
};

public enum SlangCapabilityID
{
    SLANG_CAPABILITY_UNKNOWN = 0,
};

public enum SlangMatrixLayoutMode
{
    SLANG_MATRIX_LAYOUT_MODE_UNKNOWN = 0,
    SLANG_MATRIX_LAYOUT_ROW_MAJOR,
    SLANG_MATRIX_LAYOUT_COLUMN_MAJOR,
};

public enum SlangStage
{
    SLANG_STAGE_NONE,
    SLANG_STAGE_VERTEX,
    SLANG_STAGE_HULL,
    SLANG_STAGE_DOMAIN,
    SLANG_STAGE_GEOMETRY,
    SLANG_STAGE_FRAGMENT,
    SLANG_STAGE_COMPUTE,
    SLANG_STAGE_RAY_GENERATION,
    SLANG_STAGE_INTERSECTION,
    SLANG_STAGE_ANY_HIT,
    SLANG_STAGE_CLOSEST_HIT,
    SLANG_STAGE_MISS,
    SLANG_STAGE_CALLABLE,
    SLANG_STAGE_MESH,
    SLANG_STAGE_AMPLIFICATION,
};

public enum SlangDebugInfoLevel
{
    SLANG_DEBUG_INFO_LEVEL_NONE = 0, /**< Don't emit debug information at all. */
    SLANG_DEBUG_INFO_LEVEL_MINIMAL,  /**< Emit as little debug information as possible, while still supporting stack trackes. */
    SLANG_DEBUG_INFO_LEVEL_STANDARD, /**< Emit whatever is the standard level of debug information for each target. */
    SLANG_DEBUG_INFO_LEVEL_MAXIMAL,  /**< Emit as much debug infromation as possible for each target. */
};

public enum SlangOptimizationLevel
{
    SLANG_OPTIMIZATION_LEVEL_NONE = 0, /**< Don't optimize at all. */
    SLANG_OPTIMIZATION_LEVEL_DEFAULT,  /**< Default optimization level: balance code quality and compilation time. */
    SLANG_OPTIMIZATION_LEVEL_HIGH,     /**< Optimize aggressively. */
    SLANG_OPTIMIZATION_LEVEL_MAXIMAL,  /**< Include optimizations that may take a very long time, or may involve severe space-vs-speed tradeoffs */
};
public enum SlangTypeKind
{
    NONE,
    STRUCT,
    ARRAY,
    MATRIX,
    VECTOR,
    SCALAR,
    CONSTANT_BUFFER,
    RESOURCE,
    SAMPLER_STATE,
    TEXTURE_BUFFER,
    SHADER_STORAGE_BUFFER,
    PARAMETER_BLOCK,
    GENERIC_TYPE_PARAMETER,
    INTERFACE,
    OUTPUT_STREAM,
    SPECIALIZED,
    FEEDBACK,
    COUNT,
};

public enum SlangScalarType
{
    NONE,
    VOID,
    BOOL,
    INT32,
    UINT32,
    INT64,
    UINT64,
    FLOAT16,
    FLOAT32,
    FLOAT64,
    INT8,
    UINT8,
    INT16,
    UINT16,
};

public struct TypeReflection
{
};

public enum CompileStdLibFlags
{
    WriteDocumentation = 0x1,
};

[COM("8BA5FB08-5195-40e2-AC58-0D-98-9C-3A-01-02")]
public interface ISlangBlob
{
    public void *getBufferPointer();
    public Size getBufferSize();
};

/** Description of a code generation target.
 */
public struct TargetDesc
{
    /** The size of this structure, in bytes.
     */
    public Size structureSize = 40;

    /** The target format to generate code for (e.g., SPIR-V, DXIL, etc.)
     */
    public SlangCompileTarget format = SlangCompileTarget.SLANG_TARGET_UNKNOWN;

    /** The compilation profile supported by the target (e.g., "Shader Model 5.1")
     */
    public SlangProfileID profile = SlangProfileID.SLANG_PROFILE_UNKNOWN;

    /** Flags for the code generation target. Currently unused. */
    public SlangTargetFlags flags = SlangTargetFlags.None;

    /** Default mode to use for floating-point operations on the target.
     */
    public SlangFloatingPointMode floatingPointMode = SlangFloatingPointMode.SLANG_FLOATING_POINT_MODE_DEFAULT;

    /** Optimization level to use for the target.
     */
    public SlangOptimizationLevel optimizationLevel = SlangOptimizationLevel.SLANG_OPTIMIZATION_LEVEL_DEFAULT;

    /** The line directive mode for output source code.
     */
    public SlangLineDirectiveMode lineDirectiveMode = SlangLineDirectiveMode.SLANG_LINE_DIRECTIVE_MODE_DEFAULT;

    /** Whether to force `scalar` layout for glsl shader storage buffers.
     */
    public bool forceGLSLScalarBufferLayout = false;
};

public enum SessionFlags
{
    kSessionFlags_None = 0
};

public struct PreprocessorMacroDesc
{
    public NativeString name;
    public NativeString value;
};

public struct SessionDesc
{
    /** The size of this structure, in bytes.
     */
    public Size structureSize = 72;

    /** Code generation targets to include in the session.
     */
    public TargetDesc *targets = nullptr;
    public Int targetCount = 0;

    /** Flags to configure the session.
     */
    public SessionFlags flags = SessionFlags.kSessionFlags_None;

    /** Default layout to assume for variables with matrix types.
     */
    public SlangMatrixLayoutMode defaultMatrixLayoutMode = SlangMatrixLayoutMode.SLANG_MATRIX_LAYOUT_ROW_MAJOR;

    /** Paths to use when searching for `#include`d or `import`ed files.
     */
    public NativeString *searchPaths = nullptr;
    public Int searchPathCount = 0;

    public PreprocessorMacroDesc *preprocessorMacros = nullptr;
    public Int preprocessorMacroCount = 0;

    public void *fileSystem = nullptr;
};

/** A global session for interaction with the Slang library.

An application may create and re-use a single global session across
multiple sessions, in order to amortize startups costs (in current
Slang this is mostly the cost of loading the Slang standard library).

The global session is currently *not* thread-safe and objects created from
a single global session should only be used from a single thread at
a time.
*/
[COM("c140b5fd-0c78-452e-ba7c-1a-1e-70-c7-f7-1c")]
public interface IGlobalSession
{
};

public enum class ContainerType
{
    None, UnsizedArray, StructuredBuffer, ConstantBuffer, ParameterBlock
};

/** A session provides a scope for code that is loaded.

A session can be used to load modules of Slang source code,
and to request target-specific compiled binaries and layout
information.

In order to be able to load code, the session owns a set
of active "search paths" for resolving `#include` directives
and `import` declrations, as well as a set of global
preprocessor definitions that will be used for all code
that gets `import`ed in the session.

If multiple user shaders are loaded in the same session,
and import the same module (e.g., two source files do `import X`)
then there will only be one copy of `X` loaded within the session.

In order to be able to generate target code, the session
owns a list of available compilation targets, which specify
code generation options.

Code loaded and compiled within a session is owned by the session
and will remain resident in memory until the session is released.
Applications wishing to control the memory usage for compiled
and loaded code should use multiple sessions.
*/
[COM("67618701-d116-468f-ab3b-47-4b-ed-ce-0e-3d")]
public interface ISession
{
};

[COM("5bc42be8-5c50-4929-9e5e-d15e7c24015f")]
public interface IComponentType
{
}

public struct TypeLayoutReflection { }

/** The kind of specialization argument. */
public enum class SpecializationArgKind : int32_t
{
    Unknown, /**< An invalid specialization argument. */
    Type,    /**< Specialize to a type. */
};

public struct SpecializationArg
{
    public SpecializationArgKind kind;
    /** A type specialization argument, used for `Kind::Type`. */
    public TypeReflection *type;
}

}
