// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

use std::sync::Arc;

use arrow_array::{ArrayRef, RecordBatch};
use arrow_schema::{DataType, Field, Schema};
use datafusion_catalog::MemTable;
use datafusion_common::error::{DataFusionError, Result as DataFusionResult};
use datafusion_ffi::table_provider::FFI_TableProvider;
use datafusion_python_util::ffi_logical_codec_from_pycapsule;
use pyo3::exceptions::PyRuntimeError;
use pyo3::types::PyCapsule;
use pyo3::{Bound, PyAny, PyResult, Python, pyclass, pymethods};

/// In order to provide a test that demonstrates different sized record batches,
/// the first batch will have num_rows, the second batch num_rows+1, and so on.
#[pyclass(
    from_py_object,
    name = "MyTableProvider",
    module = "datafusion_ffi_example",
    subclass
)]
#[derive(Clone)]
pub(crate) struct MyTableProvider {
    num_cols: usize,
    num_rows: usize,
    num_batches: usize,
}

fn create_record_batch(
    schema: &Arc<Schema>,
    num_cols: usize,
    start_value: i32,
    num_values: usize,
) -> DataFusionResult<RecordBatch> {
    let end_value = start_value + num_values as i32;
    let row_values: Vec<i32> = (start_value..end_value).collect();

    let columns: Vec<_> = (0..num_cols)
        .map(|_| Arc::new(arrow::array::Int32Array::from(row_values.clone())) as ArrayRef)
        .collect();

    RecordBatch::try_new(Arc::clone(schema), columns).map_err(DataFusionError::from)
}

impl MyTableProvider {
    pub fn create_table(&self) -> DataFusionResult<MemTable> {
        let fields: Vec<_> = (0..self.num_cols)
            .map(|idx| (b'A' + idx as u8) as char)
            .map(|col_name| Field::new(col_name, DataType::Int32, true))
            .collect();

        let schema = Arc::new(Schema::new(fields));

        let batches: DataFusionResult<Vec<_>> = (0..self.num_batches)
            .map(|batch_idx| {
                let start_value = batch_idx * self.num_rows;
                create_record_batch(
                    &schema,
                    self.num_cols,
                    start_value as i32,
                    self.num_rows + batch_idx,
                )
            })
            .collect();

        MemTable::try_new(schema, vec![batches?])
    }
}

#[pymethods]
impl MyTableProvider {
    #[new]
    pub fn new(num_cols: usize, num_rows: usize, num_batches: usize) -> Self {
        Self {
            num_cols,
            num_rows,
            num_batches,
        }
    }

    pub fn __datafusion_table_provider__<'py>(
        &self,
        py: Python<'py>,
        session: Bound<PyAny>,
    ) -> PyResult<Bound<'py, PyCapsule>> {
        let provider = self
            .create_table()
            .map_err(|e: DataFusionError| PyRuntimeError::new_err(e.to_string()))?;

        let codec = ffi_logical_codec_from_pycapsule(session, None)?;
        let provider =
            FFI_TableProvider::new_with_ffi_codec(Arc::new(provider), false, None, codec);

        PyCapsule::new_with_value(py, provider, cr"datafusion_table_provider")
    }
}
