/*
 * Copyright (c) 2021-2023, NVIDIA CORPORATION.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

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

#include <cuda_runtime.h>

#include <cstdint>

namespace cugraph::ops::graph {

/**
 * @brief Compute the reverse graph, given a ELLPACK MFG
 *
 * @param[inout] mfg_rev        The reverse MFG in CSR format.
 *                              On input, we expect the `offsets` to hold
 *                              counts for each input node already, which you
 *                              can get from `renumber`.
 * @param[in]    mfg            The regular (ELLPACK/CSR) MFG.
 * @param[inout] n_indices      Intermediate buffer for the number of edges,
 *                              only necessary if the ELLPACK variant is used.
 *                              [on host, pinned] [len = `1`]
 * @param[inout] workspace      scratch buffer. [on device]
 *                              [len = `workspace_size`] Pass a `nullptr` in
 *                              order to get to know its size.
 * @param[inout] 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(mfg_csc_rev_s32_t& mfg_rev,
                       const mfg_ellpack_s32_t& graph,
                       int32_t* n_indices,
                       void* workspace,
                       size_t& workspace_size,
                       cudaStream_t stream);
void get_reverse_graph(mfg_csc_rev_s64_t& mfg_rev,
                       const mfg_ellpack_s64_t& graph,
                       int64_t* n_indices,
                       void* workspace,
                       size_t& workspace_size,
                       cudaStream_t stream);
void get_reverse_graph(mfg_csc_rev_s32_t& mfg_rev,
                       const mfg_csc_s32_t& graph,
                       int32_t* n_indices,
                       void* workspace,
                       size_t& workspace_size,
                       cudaStream_t stream);
void get_reverse_graph(mfg_csc_rev_s64_t& mfg_rev,
                       const mfg_csc_s64_t& graph,
                       int64_t* n_indices,
                       void* workspace,
                       size_t& workspace_size,
                       cudaStream_t stream);
/** @} */

}  // namespace cugraph::ops::graph
