#include <R.h>
#include <Rinternals.h>
#include <R_ext/Rdynload.h>
#include <R.h>
#include <Rinternals.h>
#include "r_bridge.h"
#include "vtr_append.h"

/* block.c R bridge functions */
SEXP C_block_materialize(SEXP node_xptr);
SEXP C_block_lookup(SEXP block_xptr, SEXP col_name, SEXP keys, SEXP ci);
SEXP C_block_fuzzy_lookup(SEXP block_xptr, SEXP match_col, SEXP keys,
                          SEXP method, SEXP max_dist, SEXP block_col,
                          SEXP block_keys, SEXP n_threads);
#include "vtr_delete.h"
#include "vtr_diff.h"

/* tdc encode/decode bridge round-trip test entries (vtr_codec_tdc.c). */
SEXP C_tdc_encode_column(SEXP x_sexp, SEXP comp_level_sexp);
SEXP C_tdc_decode_column(SEXP raw_sexp, SEXP n_sexp, SEXP r_type_sexp);

/* tdc-backed row-group container entries (vtr1_tdc.c). */
SEXP C_write_vtr_tdc(SEXP path_sexp, SEXP df_sexp,
                     SEXP rowgroup_size_sexp, SEXP comp_level_sexp,
                     SEXP annotations_sexp);
SEXP C_read_vtr_tdc(SEXP path_sexp);
SEXP C_read_vtr_tdc_annotations(SEXP path_sexp);
SEXP C_read_vtr_tdc_stats(SEXP path_sexp);

/* VECR raster entries (r_bridge_raster.c). */
SEXP C_vec_write_raster(SEXP path_sexp, SEXP data_sexp, SEXP dims_sexp,
                        SEXP dtype_sexp, SEXP tile_size_sexp,
                        SEXP gt_sexp, SEXP epsg_sexp, SEXP nodata_sexp,
                        SEXP band_names_sexp, SEXP compression_sexp);
SEXP C_vec_open_raster(SEXP path_sexp);
SEXP C_vec_read_window(SEXP ptr_sexp, SEXP band_sexp, SEXP level_sexp,
                       SEXP col_min_sexp, SEXP row_min_sexp,
                       SEXP col_max_sexp, SEXP row_max_sexp);
SEXP C_vec_extract_points(SEXP ptr_sexp, SEXP x_sexp, SEXP y_sexp);
SEXP C_vec_close_raster(SEXP ptr_sexp);
SEXP C_vec_build_overviews(SEXP path_sexp, SEXP n_levels_sexp,
                           SEXP resampling_sexp, SEXP compression_sexp);
SEXP C_vec_to_tiff(SEXP vec_path_sexp, SEXP tiff_path_sexp,
                   SEXP use_deflate_sexp);
SEXP C_vec_write_time_cube(SEXP path_sexp, SEXP data_sexp, SEXP dims_sexp,
                           SEXP times_sexp, SEXP dtype_sexp,
                           SEXP tile_size_sexp,
                           SEXP gt_sexp, SEXP epsg_sexp, SEXP nodata_sexp,
                           SEXP band_names_sexp, SEXP compression_sexp);
SEXP C_vec_read_time_slice(SEXP ptr_sexp, SEXP band_sexp, SEXP level_sexp,
                           SEXP time_sexp,
                           SEXP col_min_sexp, SEXP row_min_sexp,
                           SEXP col_max_sexp, SEXP row_max_sexp);
SEXP C_vec_write_pixel_cube(SEXP path_sexp, SEXP data_sexp, SEXP dims_sexp,
                            SEXP times_sexp, SEXP dtype_sexp,
                            SEXP tile_size_sexp,
                            SEXP gt_sexp, SEXP epsg_sexp, SEXP nodata_sexp,
                            SEXP band_names_sexp, SEXP compression_sexp);
SEXP C_vec_read_pixel_series(SEXP ptr_sexp, SEXP col_sexp, SEXP row_sexp,
                             SEXP band_sexp, SEXP level_sexp);
SEXP C_vec_raster_times(SEXP ptr_sexp, SEXP band_sexp, SEXP level_sexp);
SEXP C_vec_raster_layout(SEXP ptr_sexp);

static const R_CallMethodDef CallEntries[] = {
    {"C_write_vtr",    (DL_FUNC) &C_write_vtr,    7},
    {"C_scan_node",    (DL_FUNC) &C_scan_node,     1},
    {"C_collect",      (DL_FUNC) &C_collect,       1},
    {"C_node_schema",  (DL_FUNC) &C_node_schema,   1},
    {"C_node_plan",    (DL_FUNC) &C_node_plan,     1},
    {"C_filter_node",  (DL_FUNC) &C_filter_node,   2},
    {"C_project_node",   (DL_FUNC) &C_project_node,  3},
    {"C_group_agg_node", (DL_FUNC) &C_group_agg_node, 3},
    {"C_sort_node",      (DL_FUNC) &C_sort_node,       3},
    {"C_limit_node",     (DL_FUNC) &C_limit_node,      2},
    {"C_topn_node",      (DL_FUNC) &C_topn_node,       4},
    {"C_join_node",      (DL_FUNC) &C_join_node,       7},
    {"C_window_node",    (DL_FUNC) &C_window_node,     3},
    {"C_concat_node",   (DL_FUNC) &C_concat_node,    1},
    {"C_write_csv",     (DL_FUNC) &C_write_csv,      2},
    {"C_csv_scan_node", (DL_FUNC) &C_csv_scan_node,  2},
    {"C_sql_scan_node", (DL_FUNC) &C_sql_scan_node,  3},
    {"C_write_sqlite",  (DL_FUNC) &C_write_sqlite,   3},
    {"C_tiff_scan_node", (DL_FUNC) &C_tiff_scan_node, 2},
    {"C_tiff_scan_meta",         (DL_FUNC) &C_tiff_scan_meta,         1},
    {"C_tiff_extract_points",    (DL_FUNC) &C_tiff_extract_points,    3},
    {"C_write_tiff",             (DL_FUNC) &C_write_tiff,             3},
    {"C_write_tiff_typed",       (DL_FUNC) &C_write_tiff_typed,       11},
    {"C_tiff_read_metadata",     (DL_FUNC) &C_tiff_read_metadata,     1},
    {"C_tiff_read_crs",          (DL_FUNC) &C_tiff_read_crs,          1},
    {"C_write_vtr_node", (DL_FUNC) &C_write_vtr_node, 7},
    {"C_append_vtr",     (DL_FUNC) &C_append_vtr,     2},
    {"C_delete_vtr",     (DL_FUNC) &C_delete_vtr,      2},
    {"C_diff_vtr",       (DL_FUNC) &C_diff_vtr,        3},
    {"C_fuzzy_join_node", (DL_FUNC) &C_fuzzy_join_node, 10},
    {"C_block_materialize", (DL_FUNC) &C_block_materialize, 1},
    {"C_block_lookup",        (DL_FUNC) &C_block_lookup,        4},
    {"C_block_fuzzy_lookup",  (DL_FUNC) &C_block_fuzzy_lookup,  8},
    {"C_create_index",      (DL_FUNC) &C_create_index,      3},
    {"C_has_index",         (DL_FUNC) &C_has_index,         2},
    {"C_tdc_encode_column",   (DL_FUNC) &C_tdc_encode_column,   2},
    {"C_tdc_decode_column",   (DL_FUNC) &C_tdc_decode_column,   3},
    {"C_write_vtr_tdc",            (DL_FUNC) &C_write_vtr_tdc,            5},
    {"C_read_vtr_tdc",             (DL_FUNC) &C_read_vtr_tdc,             1},
    {"C_read_vtr_tdc_annotations", (DL_FUNC) &C_read_vtr_tdc_annotations, 1},
    {"C_read_vtr_tdc_stats",       (DL_FUNC) &C_read_vtr_tdc_stats,       1},
    {"C_vec_write_raster",         (DL_FUNC) &C_vec_write_raster,         10},
    {"C_vec_open_raster",          (DL_FUNC) &C_vec_open_raster,          1},
    {"C_vec_read_window",          (DL_FUNC) &C_vec_read_window,          7},
    {"C_vec_extract_points",       (DL_FUNC) &C_vec_extract_points,       3},
    {"C_vec_close_raster",         (DL_FUNC) &C_vec_close_raster,         1},
    {"C_vec_build_overviews",      (DL_FUNC) &C_vec_build_overviews,      4},
    {"C_vec_to_tiff",              (DL_FUNC) &C_vec_to_tiff,              3},
    {"C_vec_write_time_cube",      (DL_FUNC) &C_vec_write_time_cube,      11},
    {"C_vec_read_time_slice",      (DL_FUNC) &C_vec_read_time_slice,      8},
    {"C_vec_write_pixel_cube",     (DL_FUNC) &C_vec_write_pixel_cube,     11},
    {"C_vec_read_pixel_series",    (DL_FUNC) &C_vec_read_pixel_series,    5},
    {"C_vec_raster_times",         (DL_FUNC) &C_vec_raster_times,         3},
    {"C_vec_raster_layout",        (DL_FUNC) &C_vec_raster_layout,        1},
    {NULL, NULL, 0}
};

void R_init_vectra(DllInfo *dll) {
    R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
    R_useDynamicSymbols(dll, FALSE);
}
