#ifndef CITYJSON_LIB_FFI_CORE_H
#define CITYJSON_LIB_FFI_CORE_H

#pragma once

/* This file is generated by cbindgen. Do not edit. */

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/**
 * Stable status codes for the shared C ABI.
 */
typedef enum cj_status_t {
  CJ_STATUS_SUCCESS = 0,
  CJ_STATUS_INVALID_ARGUMENT = 1,
  CJ_STATUS_IO = 2,
  CJ_STATUS_SYNTAX = 3,
  CJ_STATUS_VERSION = 4,
  CJ_STATUS_SHAPE = 5,
  CJ_STATUS_UNSUPPORTED = 6,
  CJ_STATUS_MODEL = 7,
  CJ_STATUS_INTERNAL = 8,
} cj_status_t;

/**
 * Stable geometry type discriminant for stored `CityJSON` geometries.
 */
typedef enum cj_geometry_type_t {
  CJ_GEOMETRY_TYPE_MULTI_POINT = 0,
  CJ_GEOMETRY_TYPE_MULTI_LINE_STRING = 1,
  CJ_GEOMETRY_TYPE_MULTI_SURFACE = 2,
  CJ_GEOMETRY_TYPE_COMPOSITE_SURFACE = 3,
  CJ_GEOMETRY_TYPE_SOLID = 4,
  CJ_GEOMETRY_TYPE_MULTI_SOLID = 5,
  CJ_GEOMETRY_TYPE_COMPOSITE_SOLID = 6,
  CJ_GEOMETRY_TYPE_GEOMETRY_INSTANCE = 7,
} cj_geometry_type_t;

/**
 * Stable error categories for the shared C ABI.
 */
typedef enum cj_error_kind_t {
  CJ_ERROR_KIND_NONE = 0,
  CJ_ERROR_KIND_INVALID_ARGUMENT = 1,
  CJ_ERROR_KIND_IO = 2,
  CJ_ERROR_KIND_SYNTAX = 3,
  CJ_ERROR_KIND_VERSION = 4,
  CJ_ERROR_KIND_SHAPE = 5,
  CJ_ERROR_KIND_UNSUPPORTED = 6,
  CJ_ERROR_KIND_MODEL = 7,
  CJ_ERROR_KIND_INTERNAL = 8,
} cj_error_kind_t;

/**
 * Stable root type discriminant for probed inputs.
 */
typedef enum cj_root_kind_t {
  CJ_ROOT_KIND_CITY_JSON = 0,
  CJ_ROOT_KIND_CITY_JSON_FEATURE = 1,
} cj_root_kind_t;

/**
 * Stable version discriminant for probed inputs.
 */
typedef enum cj_version_t {
  CJ_VERSION_UNKNOWN = 0,
  CJ_VERSION_V1_0 = 1,
  CJ_VERSION_V1_1 = 2,
  CJ_VERSION_V2_0 = 3,
} cj_version_t;

/**
 * Stable model type discriminant for `CityJSON` documents and features.
 */
typedef enum cj_model_type_t {
  CJ_MODEL_TYPE_CITY_JSON = 0,
  CJ_MODEL_TYPE_CITY_JSON_FEATURE = 1,
} cj_model_type_t;

/**
 * Stable contact-role discriminant.
 */
typedef enum cj_contact_role_t {
  CJ_CONTACT_ROLE_AUTHOR = 0,
  CJ_CONTACT_ROLE_CO_AUTHOR = 1,
  CJ_CONTACT_ROLE_PROCESSOR = 2,
  CJ_CONTACT_ROLE_POINT_OF_CONTACT = 3,
  CJ_CONTACT_ROLE_OWNER = 4,
  CJ_CONTACT_ROLE_USER = 5,
  CJ_CONTACT_ROLE_DISTRIBUTOR = 6,
  CJ_CONTACT_ROLE_ORIGINATOR = 7,
  CJ_CONTACT_ROLE_CUSTODIAN = 8,
  CJ_CONTACT_ROLE_RESOURCE_PROVIDER = 9,
  CJ_CONTACT_ROLE_RIGHTS_HOLDER = 10,
  CJ_CONTACT_ROLE_SPONSOR = 11,
  CJ_CONTACT_ROLE_PRINCIPAL_INVESTIGATOR = 12,
  CJ_CONTACT_ROLE_STAKEHOLDER = 13,
  CJ_CONTACT_ROLE_PUBLISHER = 14,
} cj_contact_role_t;

/**
 * Stable contact-type discriminant.
 */
typedef enum cj_contact_type_t {
  CJ_CONTACT_TYPE_INDIVIDUAL = 0,
  CJ_CONTACT_TYPE_ORGANIZATION = 1,
} cj_contact_type_t;

/**
 * Stable texture image-type discriminant.
 */
typedef enum cj_image_type_t {
  CJ_IMAGE_TYPE_PNG = 0,
  CJ_IMAGE_TYPE_JPG = 1,
} cj_image_type_t;

/**
 * Stable texture wrap-mode discriminant.
 */
typedef enum cj_wrap_mode_t {
  CJ_WRAP_MODE_WRAP = 0,
  CJ_WRAP_MODE_MIRROR = 1,
  CJ_WRAP_MODE_CLAMP = 2,
  CJ_WRAP_MODE_BORDER = 3,
  CJ_WRAP_MODE_NONE = 4,
} cj_wrap_mode_t;

/**
 * Stable texture-mapping discriminant.
 */
typedef enum cj_texture_type_t {
  CJ_TEXTURE_TYPE_UNKNOWN = 0,
  CJ_TEXTURE_TYPE_SPECIFIC = 1,
  CJ_TEXTURE_TYPE_TYPICAL = 2,
} cj_texture_type_t;

/**
 * Opaque model handle type.
 *
 * The ABI only ever passes pointers to this marker type. The actual storage is
 * a boxed `cityjson_lib::CityModel` allocated by the Rust side.
 */
typedef struct cj_model_t {
  uint8_t _private[0];
} cj_model_t;

/**
 * Opaque model-selection handle type.
 *
 * The ABI only ever passes pointers to this marker type. The actual storage is
 * a boxed `cityjson_lib::ops::ModelSelection` allocated by the Rust side.
 */
typedef struct cj_model_selection_t {
  uint8_t _private[0];
} cj_model_selection_t;

/**
 * Owned byte buffer returned across the ABI.
 */
typedef struct cj_bytes_t {
  uint8_t *data;
  uintptr_t len;
} cj_bytes_t;

/**
 * Owned byte-buffer list returned across the ABI.
 */
typedef struct cj_bytes_list_t {
  struct cj_bytes_t *data;
  uintptr_t len;
} cj_bytes_list_t;

/**
 * Packed 3D coordinate copied across the ABI.
 */
typedef struct cj_vertex_t {
  double x;
  double y;
  double z;
} cj_vertex_t;

/**
 * Owned vertex buffer returned across the ABI.
 */
typedef struct cj_vertices_t {
  struct cj_vertex_t *data;
  uintptr_t len;
} cj_vertices_t;

/**
 * Owned geometry-type list returned across the ABI.
 */
typedef struct cj_geometry_types_t {
  enum cj_geometry_type_t *data;
  uintptr_t len;
} cj_geometry_types_t;

/**
 * Packed UV coordinate copied across the ABI.
 */
typedef struct cj_uv_t {
  float u;
  float v;
} cj_uv_t;

/**
 * Owned UV buffer returned across the ABI.
 */
typedef struct cj_uvs_t {
  struct cj_uv_t *data;
  uintptr_t len;
} cj_uvs_t;

/**
 * Owned index buffer returned across the ABI.
 */
typedef struct cj_indices_t {
  uintptr_t *data;
  uintptr_t len;
} cj_indices_t;

/**
 * Owned flat boundary payload returned across the ABI.
 */
typedef struct cj_geometry_boundary_t {
  enum cj_geometry_type_t geometry_type;
  bool has_boundaries;
  struct cj_indices_t vertex_indices;
  struct cj_indices_t ring_offsets;
  struct cj_indices_t surface_offsets;
  struct cj_indices_t shell_offsets;
  struct cj_indices_t solid_offsets;
} cj_geometry_boundary_t;

/**
 * Opaque typed value handle.
 */
typedef struct cj_value_t {
  uint8_t _private[0];
} cj_value_t;

/**
 * Opaque metadata-contact authoring handle.
 */
typedef struct cj_contact_t {
  uint8_t _private[0];
} cj_contact_t;

/**
 * Opaque cityobject-draft authoring handle.
 */
typedef struct cj_cityobject_draft_t {
  uint8_t _private[0];
} cj_cityobject_draft_t;

/**
 * Opaque ring-draft authoring handle.
 */
typedef struct cj_ring_draft_t {
  uint8_t _private[0];
} cj_ring_draft_t;

/**
 * Opaque surface-draft authoring handle.
 */
typedef struct cj_surface_draft_t {
  uint8_t _private[0];
} cj_surface_draft_t;

/**
 * Opaque shell-draft authoring handle.
 */
typedef struct cj_shell_draft_t {
  uint8_t _private[0];
} cj_shell_draft_t;

/**
 * Opaque solid-draft authoring handle.
 */
typedef struct cj_solid_draft_t {
  uint8_t _private[0];
} cj_solid_draft_t;

/**
 * Opaque geometry-draft authoring handle.
 */
typedef struct cj_geometry_draft_t {
  uint8_t _private[0];
} cj_geometry_draft_t;

/**
 * Probe result returned by the low-level ABI.
 */
typedef struct cj_probe_t {
  enum cj_root_kind_t root_kind;
  enum cj_version_t version;
  bool has_version;
} cj_probe_t;

/**
 * Borrowed UTF-8 string view passed into the ABI.
 */
typedef struct cj_string_view_t {
  const uint8_t *data;
  uintptr_t len;
} cj_string_view_t;

/**
 * Aggregate model inspection summary returned across the ABI.
 */
typedef struct cj_model_summary_t {
  enum cj_model_type_t model_type;
  enum cj_version_t version;
  uintptr_t cityobject_count;
  uintptr_t geometry_count;
  uintptr_t geometry_template_count;
  uintptr_t vertex_count;
  uintptr_t template_vertex_count;
  uintptr_t uv_coordinate_count;
  uintptr_t semantic_count;
  uintptr_t material_count;
  uintptr_t texture_count;
  uintptr_t extension_count;
  bool has_metadata;
  bool has_transform;
  bool has_templates;
  bool has_appearance;
} cj_model_summary_t;

/**
 * Capacity hints for bulk import and model-building paths.
 */
typedef struct cj_model_capacities_t {
  uintptr_t cityobjects;
  uintptr_t vertices;
  uintptr_t semantics;
  uintptr_t materials;
  uintptr_t textures;
  uintptr_t geometries;
  uintptr_t template_vertices;
  uintptr_t template_geometries;
  uintptr_t uv_coordinates;
} cj_model_capacities_t;

/**
 * Explicit root-transform state for JSON write and edit workflows.
 */
typedef struct cj_transform_t {
  double scale_x;
  double scale_y;
  double scale_z;
  double translate_x;
  double translate_y;
  double translate_z;
} cj_transform_t;

/**
 * Borrowed index-slice view passed into the ABI.
 */
typedef struct cj_indices_view_t {
  const uintptr_t *data;
  uintptr_t len;
} cj_indices_view_t;

/**
 * Borrowed flat boundary payload passed into the ABI.
 */
typedef struct cj_geometry_boundary_view_t {
  enum cj_geometry_type_t geometry_type;
  struct cj_indices_view_t vertex_indices;
  struct cj_indices_view_t ring_offsets;
  struct cj_indices_view_t surface_offsets;
  struct cj_indices_view_t shell_offsets;
  struct cj_indices_view_t solid_offsets;
} cj_geometry_boundary_view_t;

/**
 * CityObject id and geometry index pair used by model-selection APIs.
 */
typedef struct cj_geometry_selection_spec_t {
  struct cj_string_view_t cityobject_id;
  uintptr_t geometry_index;
} cj_geometry_selection_spec_t;

/**
 * Explicit JSON write options for document, feature, and feature-stream output.
 */
typedef struct cj_json_write_options_t {
  bool pretty;
  bool validate_default_themes;
} cj_json_write_options_t;

/**
 * Explicit strict `CityJSONSeq` write options.
 */
typedef struct cj_cityjsonseq_write_options_t {
  bool validate_default_themes;
  bool trailing_newline;
  bool update_metadata_geographical_extent;
} cj_cityjsonseq_write_options_t;

/**
 * Auto-transform options for strict `CityJSONSeq` writing.
 */
typedef struct cj_cityjsonseq_auto_transform_options_t {
  double scale_x;
  double scale_y;
  double scale_z;
  bool validate_default_themes;
  bool trailing_newline;
  bool update_metadata_geographical_extent;
} cj_cityjsonseq_auto_transform_options_t;

/**
 * Stable typed id for a model-owned geometry handle.
 */
typedef struct cj_geometry_id_t {
  uint32_t slot;
  uint16_t generation;
  uint16_t reserved;
} cj_geometry_id_t;

/**
 * Packed bbox copied across the ABI.
 */
typedef struct cj_bbox_t {
  double min_x;
  double min_y;
  double min_z;
  double max_x;
  double max_y;
  double max_z;
} cj_bbox_t;

/**
 * Stable typed id for a model-owned semantic handle.
 */
typedef struct cj_semantic_id_t {
  uint32_t slot;
  uint16_t generation;
  uint16_t reserved;
} cj_semantic_id_t;

/**
 * Stable typed id for a model-owned material handle.
 */
typedef struct cj_material_id_t {
  uint32_t slot;
  uint16_t generation;
  uint16_t reserved;
} cj_material_id_t;

/**
 * Packed RGB color copied across the ABI.
 */
typedef struct cj_rgb_t {
  float r;
  float g;
  float b;
} cj_rgb_t;

/**
 * Stable typed id for a model-owned texture handle.
 */
typedef struct cj_texture_id_t {
  uint32_t slot;
  uint16_t generation;
  uint16_t reserved;
} cj_texture_id_t;

/**
 * Packed RGBA color copied across the ABI.
 */
typedef struct cj_rgba_t {
  float r;
  float g;
  float b;
  float a;
} cj_rgba_t;

/**
 * Stable typed id for a model-owned cityobject handle.
 */
typedef struct cj_cityobject_id_t {
  uint32_t slot;
  uint16_t generation;
  uint16_t reserved;
} cj_cityobject_id_t;

/**
 * Stable typed id for a model-owned template-geometry handle.
 */
typedef struct cj_geometry_template_id_t {
  uint32_t slot;
  uint16_t generation;
  uint16_t reserved;
} cj_geometry_template_id_t;

/**
 * Packed 4x4 affine transform copied across the ABI.
 */
typedef struct cj_affine_transform_4x4_t {
  double elements[16];
} cj_affine_transform_4x4_t;

/**
 * Opaque handle for a cached PROJ coordinate transformer.
 */
typedef struct cj_proj_transformer_t {
  uint8_t _private[0];
} cj_proj_transformer_t;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

enum cj_status_t cj_model_free(struct cj_model_t *handle);

enum cj_status_t cj_model_selection_free(struct cj_model_selection_t *handle);

enum cj_status_t cj_bytes_free(struct cj_bytes_t bytes);

enum cj_status_t cj_bytes_list_free(struct cj_bytes_list_t bytes);

enum cj_status_t cj_vertices_free(struct cj_vertices_t vertices);

enum cj_status_t cj_geometry_types_free(struct cj_geometry_types_t types);

enum cj_status_t cj_uvs_free(struct cj_uvs_t uvs);

enum cj_status_t cj_indices_free(struct cj_indices_t indices);

enum cj_status_t cj_geometry_boundary_free(struct cj_geometry_boundary_t boundary);

enum cj_status_t cj_value_free(struct cj_value_t *handle);

enum cj_status_t cj_contact_free(struct cj_contact_t *handle);

enum cj_status_t cj_cityobject_draft_free(struct cj_cityobject_draft_t *handle);

enum cj_status_t cj_ring_draft_free(struct cj_ring_draft_t *handle);

enum cj_status_t cj_surface_draft_free(struct cj_surface_draft_t *handle);

enum cj_status_t cj_shell_draft_free(struct cj_shell_draft_t *handle);

enum cj_status_t cj_solid_draft_free(struct cj_solid_draft_t *handle);

enum cj_status_t cj_geometry_draft_free(struct cj_geometry_draft_t *handle);

enum cj_error_kind_t cj_last_error_kind(void);

uintptr_t cj_last_error_message_len(void);

enum cj_status_t cj_last_error_message_copy(uint8_t *buffer,
                                            uintptr_t capacity,
                                            uintptr_t *out_len);

enum cj_status_t cj_clear_error(void);

enum cj_status_t cj_probe_bytes(const uint8_t *data, uintptr_t len, struct cj_probe_t *out_probe);

enum cj_status_t cj_model_parse_document_bytes(const uint8_t *data,
                                               uintptr_t len,
                                               struct cj_model_t **out_model);

enum cj_status_t cj_model_parse_feature_bytes(const uint8_t *data,
                                              uintptr_t len,
                                              struct cj_model_t **out_model);

enum cj_status_t cj_model_parse_feature_with_base_bytes(const uint8_t *feature_data,
                                                        uintptr_t feature_len,
                                                        const uint8_t *base_data,
                                                        uintptr_t base_len,
                                                        struct cj_model_t **out_model);

#if defined(CITYJSON_LIB_NATIVE_FORMATS)
enum cj_status_t cj_model_parse_arrow_bytes(const uint8_t *data,
                                            uintptr_t len,
                                            struct cj_model_t **out_model);
#endif

#if defined(CITYJSON_LIB_NATIVE_FORMATS)
enum cj_status_t cj_model_parse_parquet_file(struct cj_string_view_t path,
                                             struct cj_model_t **out_model);
#endif

#if defined(CITYJSON_LIB_NATIVE_FORMATS)
enum cj_status_t cj_model_parse_parquet_dataset_dir(struct cj_string_view_t path,
                                                    struct cj_model_t **out_model);
#endif

enum cj_status_t cj_model_serialize_document(const struct cj_model_t *model,
                                             struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_serialize_feature(const struct cj_model_t *model,
                                            struct cj_bytes_t *out_bytes);

#if defined(CITYJSON_LIB_NATIVE_FORMATS)
enum cj_status_t cj_model_serialize_arrow_bytes(const struct cj_model_t *model,
                                                struct cj_bytes_t *out_bytes);
#endif

#if defined(CITYJSON_LIB_NATIVE_FORMATS)
enum cj_status_t cj_model_serialize_parquet_file(const struct cj_model_t *model,
                                                 struct cj_string_view_t path);
#endif

#if defined(CITYJSON_LIB_NATIVE_FORMATS)
enum cj_status_t cj_model_serialize_parquet_dataset_dir(const struct cj_model_t *model,
                                                        struct cj_string_view_t path);
#endif

enum cj_status_t cj_model_get_summary(const struct cj_model_t *model,
                                      struct cj_model_summary_t *out_summary);

enum cj_status_t cj_model_get_metadata_title(const struct cj_model_t *model,
                                             struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_get_metadata_identifier(const struct cj_model_t *model,
                                                  struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_get_cityobject_id(const struct cj_model_t *model,
                                            uintptr_t index,
                                            struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_copy_cityobject_ids(const struct cj_model_t *model,
                                              struct cj_bytes_list_t *out_ids);

enum cj_status_t cj_model_get_geometry_type(const struct cj_model_t *model,
                                            uintptr_t index,
                                            enum cj_geometry_type_t *out_type);

enum cj_status_t cj_model_copy_geometry_types(const struct cj_model_t *model,
                                              struct cj_geometry_types_t *out_types);

enum cj_status_t cj_model_copy_geometry_boundary(const struct cj_model_t *model,
                                                 uintptr_t index,
                                                 struct cj_geometry_boundary_t *out_boundary);

enum cj_status_t cj_model_copy_geometry_boundary_coordinates(const struct cj_model_t *model,
                                                             uintptr_t index,
                                                             struct cj_vertices_t *out_vertices);

enum cj_status_t cj_model_copy_vertices(const struct cj_model_t *model,
                                        struct cj_vertices_t *out_vertices);

enum cj_status_t cj_model_copy_template_vertices(const struct cj_model_t *model,
                                                 struct cj_vertices_t *out_vertices);

enum cj_status_t cj_model_copy_uv_coordinates(const struct cj_model_t *model,
                                              struct cj_uvs_t *out_uvs);

enum cj_status_t cj_model_create(enum cj_model_type_t model_type, struct cj_model_t **out_model);

enum cj_status_t cj_model_reserve_import(struct cj_model_t *model,
                                         struct cj_model_capacities_t capacities);

enum cj_status_t cj_model_add_vertex(struct cj_model_t *model,
                                     struct cj_vertex_t vertex,
                                     uintptr_t *out_index);

enum cj_status_t cj_model_add_template_vertex(struct cj_model_t *model,
                                              struct cj_vertex_t vertex,
                                              uintptr_t *out_index);

enum cj_status_t cj_model_set_vertex(struct cj_model_t *model,
                                     uintptr_t index,
                                     struct cj_vertex_t vertex);

enum cj_status_t cj_model_set_template_vertex(struct cj_model_t *model,
                                              uintptr_t index,
                                              struct cj_vertex_t vertex);

enum cj_status_t cj_model_add_uv_coordinate(struct cj_model_t *model,
                                            struct cj_uv_t uv,
                                            uintptr_t *out_index);

enum cj_status_t cj_model_set_metadata_title(struct cj_model_t *model,
                                             struct cj_string_view_t title);

enum cj_status_t cj_model_set_metadata_identifier(struct cj_model_t *model,
                                                  struct cj_string_view_t identifier);

enum cj_status_t cj_model_set_transform(struct cj_model_t *model, struct cj_transform_t transform);

enum cj_status_t cj_model_clear_transform(struct cj_model_t *model);

enum cj_status_t cj_model_reproject(struct cj_model_t *model, struct cj_string_view_t target_crs);

enum cj_status_t cj_model_remove_cityobject(struct cj_model_t *model, struct cj_string_view_t id);

enum cj_status_t cj_model_attach_geometry_to_cityobject(struct cj_model_t *model,
                                                        struct cj_string_view_t cityobject_id,
                                                        uintptr_t geometry_index);

enum cj_status_t cj_model_clear_cityobject_geometry(struct cj_model_t *model,
                                                    struct cj_string_view_t cityobject_id);

enum cj_status_t cj_model_add_geometry_from_boundary(struct cj_model_t *model,
                                                     struct cj_geometry_boundary_view_t boundary,
                                                     struct cj_string_view_t lod,
                                                     uintptr_t *out_index);

enum cj_status_t cj_model_cleanup(struct cj_model_t *model);

enum cj_status_t cj_model_append_model(struct cj_model_t *target_model,
                                       const struct cj_model_t *source_model);

enum cj_status_t cj_model_subset_cityobjects(const struct cj_model_t *model,
                                             const struct cj_string_view_t *cityobject_ids,
                                             uintptr_t cityobject_count,
                                             bool exclude,
                                             struct cj_model_t **out_model);

enum cj_status_t cj_model_select_cityobjects_by_id(const struct cj_model_t *model,
                                                   const struct cj_string_view_t *cityobject_ids,
                                                   uintptr_t cityobject_count,
                                                   struct cj_model_selection_t **out_selection);

enum cj_status_t cj_model_select_geometries_by_cityobject_id_and_index(const struct cj_model_t *model,
                                                                       const struct cj_geometry_selection_spec_t *specs,
                                                                       uintptr_t spec_count,
                                                                       struct cj_model_selection_t **out_selection);

enum cj_status_t cj_model_selection_include_relatives(const struct cj_model_selection_t *selection,
                                                      const struct cj_model_t *model,
                                                      struct cj_model_selection_t **out_selection);

enum cj_status_t cj_model_selection_union(const struct cj_model_selection_t *lhs,
                                          const struct cj_model_selection_t *rhs,
                                          struct cj_model_selection_t **out_selection);

enum cj_status_t cj_model_selection_intersection(const struct cj_model_selection_t *lhs,
                                                 const struct cj_model_selection_t *rhs,
                                                 struct cj_model_selection_t **out_selection);

enum cj_status_t cj_model_selection_is_empty(const struct cj_model_selection_t *selection,
                                             bool *out_bool);

enum cj_status_t cj_model_extract_selection(const struct cj_model_t *model,
                                            const struct cj_model_selection_t *selection,
                                            struct cj_model_t **out_model);

enum cj_status_t cj_model_merge_models(const struct cj_model_t *const *models,
                                       uintptr_t model_count,
                                       struct cj_model_t **out_model);

enum cj_status_t cj_model_serialize_document_with_options(const struct cj_model_t *model,
                                                          struct cj_json_write_options_t options,
                                                          struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_serialize_feature_with_options(const struct cj_model_t *model,
                                                         struct cj_json_write_options_t options,
                                                         struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_parse_feature_stream_merge_bytes(const uint8_t *data,
                                                           uintptr_t len,
                                                           struct cj_model_t **out_model);

enum cj_status_t cj_model_serialize_feature_stream(const struct cj_model_t *const *models,
                                                   uintptr_t model_count,
                                                   struct cj_json_write_options_t options,
                                                   struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_serialize_cityjsonseq_with_transform(const struct cj_model_t *base_root,
                                                               const struct cj_model_t *const *features,
                                                               uintptr_t feature_count,
                                                               struct cj_transform_t transform,
                                                               struct cj_cityjsonseq_write_options_t options,
                                                               struct cj_bytes_t *out_bytes);

enum cj_status_t cj_model_serialize_cityjsonseq_auto_transform(const struct cj_model_t *base_root,
                                                               const struct cj_model_t *const *features,
                                                               uintptr_t feature_count,
                                                               struct cj_cityjsonseq_auto_transform_options_t options,
                                                               struct cj_bytes_t *out_bytes);

enum cj_status_t cj_value_new_null(struct cj_value_t **out_value);

enum cj_status_t cj_value_new_bool(bool value, struct cj_value_t **out_value);

enum cj_status_t cj_value_new_int64(int64_t value, struct cj_value_t **out_value);

enum cj_status_t cj_value_new_float64(double value, struct cj_value_t **out_value);

enum cj_status_t cj_value_new_string(struct cj_string_view_t value, struct cj_value_t **out_value);

enum cj_status_t cj_value_new_array(struct cj_value_t **out_value);

enum cj_status_t cj_value_new_object(struct cj_value_t **out_value);

enum cj_status_t cj_value_new_geometry_ref(struct cj_geometry_id_t value,
                                           struct cj_value_t **out_value);

enum cj_status_t cj_value_array_push(struct cj_value_t *array_value, struct cj_value_t *element);

enum cj_status_t cj_value_object_insert(struct cj_value_t *object_value,
                                        struct cj_string_view_t key,
                                        struct cj_value_t *member_value);

enum cj_status_t cj_contact_new(struct cj_contact_t **out_contact);

enum cj_status_t cj_contact_set_name(struct cj_contact_t *contact, struct cj_string_view_t value);

enum cj_status_t cj_contact_set_email(struct cj_contact_t *contact, struct cj_string_view_t value);

enum cj_status_t cj_contact_set_role(struct cj_contact_t *contact, enum cj_contact_role_t value);

enum cj_status_t cj_contact_set_website(struct cj_contact_t *contact,
                                        struct cj_string_view_t value);

enum cj_status_t cj_contact_set_type(struct cj_contact_t *contact, enum cj_contact_type_t value);

enum cj_status_t cj_contact_set_phone(struct cj_contact_t *contact, struct cj_string_view_t value);

enum cj_status_t cj_contact_set_organization(struct cj_contact_t *contact,
                                             struct cj_string_view_t value);

enum cj_status_t cj_contact_set_address(struct cj_contact_t *contact,
                                        struct cj_value_t *object_value);

enum cj_status_t cj_model_set_metadata_geographical_extent(struct cj_model_t *model,
                                                           struct cj_bbox_t bbox);

enum cj_status_t cj_model_set_metadata_reference_date(struct cj_model_t *model,
                                                      struct cj_string_view_t value);

enum cj_status_t cj_model_set_metadata_reference_system(struct cj_model_t *model,
                                                        struct cj_string_view_t value);

enum cj_status_t cj_model_set_metadata_contact(struct cj_model_t *model,
                                               struct cj_contact_t *contact);

enum cj_status_t cj_model_set_metadata_extra(struct cj_model_t *model,
                                             struct cj_string_view_t key,
                                             struct cj_value_t *value);

enum cj_status_t cj_model_set_root_extra(struct cj_model_t *model,
                                         struct cj_string_view_t key,
                                         struct cj_value_t *value);

enum cj_status_t cj_model_add_extension(struct cj_model_t *model,
                                        struct cj_string_view_t name,
                                        struct cj_string_view_t url,
                                        struct cj_string_view_t version);

enum cj_status_t cj_model_add_semantic(struct cj_model_t *model,
                                       struct cj_string_view_t semantic_type,
                                       struct cj_semantic_id_t *out_id);

enum cj_status_t cj_model_set_semantic_parent(struct cj_model_t *model,
                                              struct cj_semantic_id_t semantic,
                                              struct cj_semantic_id_t parent);

enum cj_status_t cj_model_semantic_set_extra(struct cj_model_t *model,
                                             struct cj_semantic_id_t semantic,
                                             struct cj_string_view_t key,
                                             struct cj_value_t *value);

enum cj_status_t cj_model_add_material(struct cj_model_t *model,
                                       struct cj_string_view_t name,
                                       struct cj_material_id_t *out_id);

enum cj_status_t cj_model_material_set_ambient_intensity(struct cj_model_t *model,
                                                         struct cj_material_id_t material,
                                                         float value);

enum cj_status_t cj_model_material_set_diffuse_color(struct cj_model_t *model,
                                                     struct cj_material_id_t material,
                                                     struct cj_rgb_t value);

enum cj_status_t cj_model_material_set_emissive_color(struct cj_model_t *model,
                                                      struct cj_material_id_t material,
                                                      struct cj_rgb_t value);

enum cj_status_t cj_model_material_set_specular_color(struct cj_model_t *model,
                                                      struct cj_material_id_t material,
                                                      struct cj_rgb_t value);

enum cj_status_t cj_model_material_set_shininess(struct cj_model_t *model,
                                                 struct cj_material_id_t material,
                                                 float value);

enum cj_status_t cj_model_material_set_transparency(struct cj_model_t *model,
                                                    struct cj_material_id_t material,
                                                    float value);

enum cj_status_t cj_model_material_set_is_smooth(struct cj_model_t *model,
                                                 struct cj_material_id_t material,
                                                 bool value);

enum cj_status_t cj_model_add_texture(struct cj_model_t *model,
                                      struct cj_string_view_t image,
                                      enum cj_image_type_t image_type,
                                      struct cj_texture_id_t *out_id);

enum cj_status_t cj_model_texture_set_wrap_mode(struct cj_model_t *model,
                                                struct cj_texture_id_t texture,
                                                enum cj_wrap_mode_t value);

enum cj_status_t cj_model_texture_set_texture_type(struct cj_model_t *model,
                                                   struct cj_texture_id_t texture,
                                                   enum cj_texture_type_t value);

enum cj_status_t cj_model_texture_set_border_color(struct cj_model_t *model,
                                                   struct cj_texture_id_t texture,
                                                   struct cj_rgba_t value);

enum cj_status_t cj_model_set_default_material_theme(struct cj_model_t *model,
                                                     struct cj_string_view_t theme);

enum cj_status_t cj_model_set_default_texture_theme(struct cj_model_t *model,
                                                    struct cj_string_view_t theme);

enum cj_status_t cj_cityobject_draft_new(struct cj_string_view_t id,
                                         struct cj_string_view_t cityobject_type,
                                         struct cj_cityobject_draft_t **out_draft);

enum cj_status_t cj_cityobject_draft_set_geographical_extent(struct cj_cityobject_draft_t *draft,
                                                             struct cj_bbox_t bbox);

enum cj_status_t cj_cityobject_draft_set_attribute(struct cj_cityobject_draft_t *draft,
                                                   struct cj_string_view_t key,
                                                   struct cj_value_t *value);

enum cj_status_t cj_cityobject_draft_set_extra(struct cj_cityobject_draft_t *draft,
                                               struct cj_string_view_t key,
                                               struct cj_value_t *value);

enum cj_status_t cj_model_add_cityobject(struct cj_model_t *model,
                                         struct cj_cityobject_draft_t *draft,
                                         struct cj_cityobject_id_t *out_id);

enum cj_status_t cj_model_cityobject_add_geometry(struct cj_model_t *model,
                                                  struct cj_cityobject_id_t cityobject,
                                                  struct cj_geometry_id_t geometry);

enum cj_status_t cj_model_cityobject_add_parent(struct cj_model_t *model,
                                                struct cj_cityobject_id_t child,
                                                struct cj_cityobject_id_t parent);

enum cj_status_t cj_ring_draft_new(struct cj_ring_draft_t **out_ring);

enum cj_status_t cj_ring_draft_push_vertex_index(struct cj_ring_draft_t *ring,
                                                 uint32_t vertex_index);

enum cj_status_t cj_ring_draft_push_vertex(struct cj_ring_draft_t *ring, struct cj_vertex_t vertex);

enum cj_status_t cj_ring_draft_add_texture(struct cj_ring_draft_t *ring,
                                           struct cj_string_view_t theme,
                                           struct cj_texture_id_t texture,
                                           const uint32_t *uv_indices,
                                           uintptr_t uv_index_count);

enum cj_status_t cj_ring_draft_add_texture_uvs(struct cj_ring_draft_t *ring,
                                               struct cj_string_view_t theme,
                                               struct cj_texture_id_t texture,
                                               const struct cj_uv_t *uvs,
                                               uintptr_t uv_count);

enum cj_status_t cj_surface_draft_new(struct cj_ring_draft_t *outer,
                                      struct cj_surface_draft_t **out_surface);

enum cj_status_t cj_surface_draft_add_inner_ring(struct cj_surface_draft_t *surface,
                                                 struct cj_ring_draft_t *inner);

enum cj_status_t cj_surface_draft_set_semantic(struct cj_surface_draft_t *surface,
                                               struct cj_semantic_id_t semantic);

enum cj_status_t cj_surface_draft_add_material(struct cj_surface_draft_t *surface,
                                               struct cj_string_view_t theme,
                                               struct cj_material_id_t material);

enum cj_status_t cj_shell_draft_new(struct cj_shell_draft_t **out_shell);

enum cj_status_t cj_shell_draft_add_surface(struct cj_shell_draft_t *shell,
                                            struct cj_surface_draft_t *surface);

enum cj_status_t cj_solid_draft_new(struct cj_shell_draft_t *outer,
                                    struct cj_solid_draft_t **out_solid);

enum cj_status_t cj_solid_draft_add_inner_shell(struct cj_solid_draft_t *solid,
                                                struct cj_shell_draft_t *inner);

enum cj_status_t cj_geometry_draft_new(enum cj_geometry_type_t geometry_type,
                                       struct cj_string_view_t lod,
                                       struct cj_geometry_draft_t **out_draft);

enum cj_status_t cj_geometry_draft_new_instance(struct cj_geometry_template_id_t template_id,
                                                uint32_t reference_vertex_index,
                                                struct cj_affine_transform_4x4_t transform,
                                                struct cj_geometry_draft_t **out_draft);

enum cj_status_t cj_geometry_draft_add_point_vertex_index(struct cj_geometry_draft_t *draft,
                                                          uint32_t vertex_index,
                                                          const struct cj_semantic_id_t *semantic);

enum cj_status_t cj_geometry_draft_add_linestring(struct cj_geometry_draft_t *draft,
                                                  const uint32_t *vertex_indices,
                                                  uintptr_t vertex_index_count,
                                                  const struct cj_semantic_id_t *semantic);

enum cj_status_t cj_geometry_draft_add_surface(struct cj_geometry_draft_t *draft,
                                               struct cj_surface_draft_t *surface);

enum cj_status_t cj_geometry_draft_add_solid(struct cj_geometry_draft_t *draft,
                                             struct cj_solid_draft_t *solid);

enum cj_status_t cj_model_add_geometry(struct cj_model_t *model,
                                       struct cj_geometry_draft_t *draft,
                                       struct cj_geometry_id_t *out_id);

enum cj_status_t cj_model_add_geometry_template(struct cj_model_t *model,
                                                struct cj_geometry_draft_t *draft,
                                                struct cj_geometry_template_id_t *out_id);

enum cj_status_t cj_proj_transformer_create(struct cj_string_view_t source_crs,
                                            struct cj_string_view_t target_crs,
                                            struct cj_proj_transformer_t **out_transformer);

enum cj_status_t cj_proj_transformer_free(struct cj_proj_transformer_t *transformer);

enum cj_status_t cj_proj_transformer_transform(const struct cj_proj_transformer_t *transformer,
                                               struct cj_vertex_t point,
                                               struct cj_vertex_t *out_point);

#ifdef __cplusplus
}  // extern "C"
#endif  // __cplusplus

#endif  /* CITYJSON_LIB_FFI_CORE_H */
