/*
 * Copyright (c) 2021-2023, NVIDIA CORPORATION. All rights reserved.
 *
 * This source code and/or documentation ("Licensed Deliverables") are
 * subject to NVIDIA intellectual property rights under U.S. and
 * international Copyright laws.
 */

#pragma once

#include <cugraph-ops/cuda/stream.hpp>
#include <cugraph-ops/graph/format.hpp>

#include <cuda_runtime.h>

#include <cstdint>

namespace cugraph::ops::graph {

/**
 * @brief Compute the reverse graph, given an existing CSC format
 *
 * @param[inout] graph          the graph (in CSC format) which is already filled
 *                              with valid `offsets` and `indices` and will
 *                              be updated to contain `rev_offsets` and rev_indices`
 *                              representing the reverse graph in CSR format.
 *                              On input, we expect the `offsets` to hold
 *                              counts for each input node already, which you
 *                              can get from `renumber`.
 * @param[inout] node_counts    scratch buffer for counting neighbors.
                                [on device] [size = `graph.n_src_nodes`]
 *                              Assumed to be allocated by the caller beforehand.
 * @param[inout] cub_workspace  scratch buffer for cub.
 *                              [on device] [size = `cub_workspace_size`]
 *                              Pass a `nullptr` in order to get to know its size.
 * @param[inout] cub_workspace_size    workspace size in bytes. If `workspace` is a
 *                                     `nullptr`, then this will be computed and the
 *                                     caller is expected to allocate the workspace
 *                                     buffer  of this size.
 * @param[in]    stream         cuda stream where to schedule work
 *
 * @{
 */
void get_reverse_graph(bipartite_csc_s32_t& graph,
                       int32_t* node_counts,
                       void* cub_workspace,
                       size_t& cub_workspace_size,
                       const cuda::stream& stream);
void get_reverse_graph(bipartite_csc_s64_t& graph,
                       int64_t* node_counts,
                       void* cub_workspace,
                       size_t& cub_workspace_size,
                       const cuda::stream& stream);
void get_reverse_graph(csc_s32_t& graph,
                       int32_t* node_counts,
                       void* cub_workspace,
                       size_t& cub_workspace_size,
                       const cuda::stream& stream);
void get_reverse_graph(csc_s64_t& graph,
                       int64_t* node_counts,
                       void* cub_workspace,
                       size_t& cub_workspace_size,
                       const cuda::stream& stream);
/** @} */

}  // namespace cugraph::ops::graph
