// 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 arrow::array::{
    Array, ArrayRef, BooleanArray, Decimal128Array, DictionaryArray, FixedSizeBinaryArray,
    FixedSizeListBuilder, Int16Array, Int32Array, Int64Array, Int64Builder, ListArray, ListBuilder,
    MapBuilder, NullArray, StringArray, StringBuilder, StringDictionaryBuilder, StructArray,
    UInt16Array, UInt16Builder, UInt8Array, UnionArray,
};
use arrow::datatypes::Int16Type;
use arrow_array::StringViewArray;
use arrow_buffer::{Buffer, ScalarBuffer};
use arrow_data::transform::MutableArrayData;
use arrow_data::ArrayData;
use arrow_schema::{DataType, Field, Fields, UnionFields};
use std::sync::Arc;

#[allow(unused)]
fn create_decimal_array(array: Vec<Option<i128>>, precision: u8, scale: i8) -> Decimal128Array {
    array
        .into_iter()
        .collect::<Decimal128Array>()
        .with_precision_and_scale(precision, scale)
        .unwrap()
}

#[test]
#[cfg(not(feature = "force_validate"))]
fn test_decimal() {
    let decimal_array =
        create_decimal_array(vec![Some(1), Some(2), None, Some(3)], 10, 3).into_data();
    let arrays = vec![&decimal_array];
    let mut a = MutableArrayData::new(arrays, true, 3);
    a.extend(0, 0, 3);
    a.extend(0, 2, 3);
    let result = a.freeze();
    let array = Decimal128Array::from(result);
    let expected = create_decimal_array(vec![Some(1), Some(2), None, None], 10, 3);
    assert_eq!(array, expected);
}
#[test]
#[cfg(not(feature = "force_validate"))]
fn test_decimal_offset() {
    let decimal_array = create_decimal_array(vec![Some(1), Some(2), None, Some(3)], 10, 3);
    let decimal_array = decimal_array.slice(1, 3).into_data(); // 2, null, 3
    let arrays = vec![&decimal_array];
    let mut a = MutableArrayData::new(arrays, true, 2);
    a.extend(0, 0, 2); // 2, null
    let result = a.freeze();
    let array = Decimal128Array::from(result);
    let expected = create_decimal_array(vec![Some(2), None], 10, 3);
    assert_eq!(array, expected);
}

#[test]
#[cfg(not(feature = "force_validate"))]
fn test_decimal_null_offset_nulls() {
    let decimal_array = create_decimal_array(vec![Some(1), Some(2), None, Some(3)], 10, 3);
    let decimal_array = decimal_array.slice(1, 3).into_data(); // 2, null, 3
    let arrays = vec![&decimal_array];
    let mut a = MutableArrayData::new(arrays, true, 2);
    a.extend(0, 0, 2); // 2, null
    a.extend_nulls(3); // 2, null, null, null, null
    a.extend(0, 1, 3); //2, null, null, null, null, null, 3
    let result = a.freeze();
    let array = Decimal128Array::from(result);
    let expected =
        create_decimal_array(vec![Some(2), None, None, None, None, None, Some(3)], 10, 3);
    assert_eq!(array, expected);
}

/// tests extending from a primitive array w/ offset nor nulls
#[test]
fn test_primitive() {
    let b = UInt8Array::from(vec![Some(1), Some(2), Some(3)]).into_data();
    let arrays = vec![&b];
    let mut a = MutableArrayData::new(arrays, false, 3);
    a.extend(0, 0, 2);
    let result = a.freeze();
    let array = UInt8Array::from(result);
    let expected = UInt8Array::from(vec![Some(1), Some(2)]);
    assert_eq!(array, expected);
}

/// tests extending from a primitive array with offset w/ nulls
#[test]
fn test_primitive_offset() {
    let b = UInt8Array::from(vec![Some(1), Some(2), Some(3)]).into_data();
    let b = b.slice(1, 2);
    let arrays = vec![&b];
    let mut a = MutableArrayData::new(arrays, false, 2);
    a.extend(0, 0, 2);
    let result = a.freeze();
    let array = UInt8Array::from(result);
    let expected = UInt8Array::from(vec![Some(2), Some(3)]);
    assert_eq!(array, expected);
}

/// tests extending from a primitive array with offset and nulls
#[test]
fn test_primitive_null_offset() {
    let b = UInt8Array::from(vec![Some(1), None, Some(3)]);
    let b = b.slice(1, 2).into_data();
    let arrays = vec![&b];
    let mut a = MutableArrayData::new(arrays, false, 2);
    a.extend(0, 0, 2);
    let result = a.freeze();
    let array = UInt8Array::from(result);
    let expected = UInt8Array::from(vec![None, Some(3)]);
    assert_eq!(array, expected);
}

#[test]
fn test_primitive_null_offset_nulls() {
    let b = UInt8Array::from(vec![Some(1), Some(2), Some(3)]).into_data();
    let b = b.slice(1, 2);
    let arrays = vec![&b];
    let mut a = MutableArrayData::new(arrays, true, 2);
    a.extend(0, 0, 2);
    a.extend_nulls(3);
    a.extend(0, 1, 2);
    let result = a.freeze();
    let array = UInt8Array::from(result);
    let expected = UInt8Array::from(vec![Some(2), Some(3), None, None, None, Some(3)]);
    assert_eq!(array, expected);
}

#[test]
fn test_list_null_offset() {
    let int_builder = Int64Builder::with_capacity(24);
    let mut builder = ListBuilder::<Int64Builder>::new(int_builder);
    builder.values().append_slice(&[1, 2, 3]);
    builder.append(true);
    builder.values().append_slice(&[4, 5]);
    builder.append(true);
    builder.values().append_slice(&[6, 7, 8]);
    builder.append(true);
    let array = builder.finish().into_data();
    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);
    mutable.extend(0, 0, 1);

    let result = mutable.freeze();
    let array = ListArray::from(result);

    let int_builder = Int64Builder::with_capacity(24);
    let mut builder = ListBuilder::<Int64Builder>::new(int_builder);
    builder.values().append_slice(&[1, 2, 3]);
    builder.append(true);
    let expected = builder.finish();

    assert_eq!(array, expected);
}

/// tests extending from a variable-sized (strings and binary) array w/ offset with nulls
#[test]
fn test_variable_sized_nulls() {
    let array = StringArray::from(vec![Some("a"), Some("bc"), None, Some("defh")]).into_data();
    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);

    let result = mutable.freeze();
    let result = StringArray::from(result);

    let expected = StringArray::from(vec![Some("bc"), None]);
    assert_eq!(result, expected);
}

/// tests extending from a variable-sized (strings and binary) array
/// with an offset and nulls
#[test]
fn test_variable_sized_offsets() {
    let array = StringArray::from(vec![Some("a"), Some("bc"), None, Some("defh")]);
    let array = array.into_data().slice(1, 3);

    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 0, 3);

    let result = mutable.freeze();
    let result = StringArray::from(result);

    let expected = StringArray::from(vec![Some("bc"), None, Some("defh")]);
    assert_eq!(result, expected);
}

#[test]
fn test_string_offsets() {
    let array = StringArray::from(vec![Some("a"), Some("bc"), None, Some("defh")]);
    let array = array.into_data().slice(1, 3);

    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 0, 3);

    let result = mutable.freeze();
    let result = StringArray::from(result);

    let expected = StringArray::from(vec![Some("bc"), None, Some("defh")]);
    assert_eq!(result, expected);
}

#[test]
fn test_multiple_with_nulls() {
    let array1 = StringArray::from(vec!["hello", "world"]).into_data();
    let array2 = StringArray::from(vec![Some("1"), None]).into_data();

    let arrays = vec![&array1, &array2];

    let mut mutable = MutableArrayData::new(arrays, false, 5);

    mutable.extend(0, 0, 2);
    mutable.extend(1, 0, 2);

    let result = mutable.freeze();
    let result = StringArray::from(result);

    let expected = StringArray::from(vec![Some("hello"), Some("world"), Some("1"), None]);
    assert_eq!(result, expected);
}

#[test]
fn test_string_null_offset_nulls() {
    let array = StringArray::from(vec![Some("a"), Some("bc"), None, Some("defh")]);
    let array = array.into_data().slice(1, 3);

    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, true, 0);

    mutable.extend(0, 1, 3);
    mutable.extend_nulls(1);

    let result = mutable.freeze();
    let result = StringArray::from(result);

    let expected = StringArray::from(vec![None, Some("defh"), None]);
    assert_eq!(result, expected);
}

#[test]
fn test_bool() {
    let array = BooleanArray::from(vec![Some(false), Some(true), None, Some(false)]).into_data();
    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);

    let result = mutable.freeze();
    let result = BooleanArray::from(result);

    let expected = BooleanArray::from(vec![Some(true), None]);
    assert_eq!(result, expected);
}

#[test]
fn test_null() {
    let array1 = NullArray::new(10).into_data();
    let array2 = NullArray::new(5).into_data();
    let arrays = vec![&array1, &array2];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);
    mutable.extend(1, 0, 1);

    let result = mutable.freeze();
    let result = NullArray::from(result);

    let expected = NullArray::new(3);
    assert_eq!(result, expected);
}

fn create_dictionary_array(values: &[&str], keys: &[Option<&str>]) -> ArrayData {
    let values = StringArray::from(values.to_vec());
    let mut builder =
        StringDictionaryBuilder::<Int16Type>::new_with_dictionary(keys.len(), &values).unwrap();
    for key in keys {
        if let Some(v) = key {
            builder.append(v).unwrap();
        } else {
            builder.append_null()
        }
    }
    builder.finish().into_data()
}

#[test]
fn test_dictionary() {
    // (a, b, c), (0, 1, 0, 2) => (a, b, a, c)
    let array = create_dictionary_array(&["a", "b", "c"], &[Some("a"), Some("b"), None, Some("c")]);
    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);

    let result = mutable.freeze();
    let result = DictionaryArray::from(result);

    let expected = Int16Array::from(vec![Some(1), None]);
    assert_eq!(result.keys(), &expected);
}

#[test]
fn test_struct() {
    let strings: ArrayRef = Arc::new(StringArray::from(vec![
        Some("joe"),
        None,
        None,
        Some("mark"),
        Some("doe"),
    ]));
    let ints: ArrayRef = Arc::new(Int32Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
    ]));

    let array = StructArray::try_from(vec![("f1", strings.clone()), ("f2", ints.clone())])
        .unwrap()
        .into_data();
    let arrays = vec![&array];
    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);
    let data = mutable.freeze();
    let array = StructArray::from(data);

    let expected =
        StructArray::try_from(vec![("f1", strings.slice(1, 2)), ("f2", ints.slice(1, 2))]).unwrap();
    assert_eq!(array, expected)
}

#[test]
fn test_struct_offset() {
    let strings: ArrayRef = Arc::new(StringArray::from(vec![
        Some("joe"),
        None,
        None,
        Some("mark"),
        Some("doe"),
    ]));
    let ints: ArrayRef = Arc::new(Int32Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
    ]));

    let array = StructArray::try_from(vec![("f1", strings.clone()), ("f2", ints.clone())])
        .unwrap()
        .into_data()
        .slice(1, 3);
    let arrays = vec![&array];
    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);
    let data = mutable.freeze();
    let array = StructArray::from(data);

    let expected_strings: ArrayRef = Arc::new(StringArray::from(vec![None, Some("mark")]));
    let expected =
        StructArray::try_from(vec![("f1", expected_strings), ("f2", ints.slice(2, 2))]).unwrap();

    assert_eq!(array, expected);
}

#[test]
fn test_struct_nulls() {
    let strings: ArrayRef = Arc::new(StringArray::from(vec![
        Some("joe"),
        None,
        None,
        Some("mark"),
        Some("doe"),
    ]));
    let ints: ArrayRef = Arc::new(Int32Array::from(vec![
        Some(1),
        Some(2),
        None,
        Some(4),
        Some(5),
    ]));

    let array = StructArray::try_from(vec![("f1", strings.clone()), ("f2", ints.clone())])
        .unwrap()
        .into_data();
    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);
    let data = mutable.freeze();
    let array = StructArray::from(data);

    let v: Vec<Option<&str>> = vec![None, None];
    let expected_string = Arc::new(StringArray::from(v)) as ArrayRef;
    let expected_int = Arc::new(Int32Array::from(vec![Some(2), None])) as ArrayRef;

    let expected =
        StructArray::try_from(vec![("f1", expected_string), ("f2", expected_int)]).unwrap();
    assert_eq!(array, expected)
}

#[test]
fn test_struct_many() {
    let strings: ArrayRef = Arc::new(StringArray::from(vec![
        Some("joe"),
        None,
        None,
        Some("mark"),
        Some("doe"),
    ]));
    let ints: ArrayRef = Arc::new(Int32Array::from(vec![
        Some(1),
        Some(2),
        None,
        Some(4),
        Some(5),
    ]));

    let array = StructArray::try_from(vec![("f1", strings.clone()), ("f2", ints.clone())])
        .unwrap()
        .into_data();
    let arrays = vec![&array, &array];
    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 3);
    mutable.extend(1, 0, 2);
    let data = mutable.freeze();
    let array = StructArray::from(data);

    let expected_string =
        Arc::new(StringArray::from(vec![None, None, Some("joe"), None])) as ArrayRef;
    let expected_int =
        Arc::new(Int32Array::from(vec![Some(2), None, Some(1), Some(2)])) as ArrayRef;

    let expected =
        StructArray::try_from(vec![("f1", expected_string), ("f2", expected_int)]).unwrap();
    assert_eq!(array, expected)
}

#[test]
fn test_union_dense() {
    // Input data
    let strings: ArrayRef = Arc::new(StringArray::from(vec![
        Some("joe"),
        Some("mark"),
        Some("doe"),
    ]));
    let ints: ArrayRef = Arc::new(Int32Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
    ]));
    let offsets = [0, 0, 1, 1, 2, 2, 3, 4]
        .into_iter()
        .collect::<ScalarBuffer<i32>>();
    let type_ids = [42, 84, 42, 84, 84, 42, 84, 84]
        .into_iter()
        .collect::<ScalarBuffer<i8>>();

    let union_fields = [
        (84, Arc::new(Field::new("int", DataType::Int32, false))),
        (42, Arc::new(Field::new("string", DataType::Utf8, false))),
    ]
    .into_iter()
    .collect::<UnionFields>();

    let array = UnionArray::try_new(
        union_fields.clone(),
        type_ids,
        Some(offsets),
        vec![ints, strings],
    )
    .unwrap()
    .into_data();
    let arrays = vec![&array];
    let mut mutable = MutableArrayData::new(arrays, false, 0);

    // Slice it by `MutableArrayData`
    mutable.extend(0, 4, 7);
    let data = mutable.freeze();
    let array = UnionArray::from(data);

    // Expected data
    let strings: ArrayRef = Arc::new(StringArray::from(vec![Some("doe")]));
    let ints: ArrayRef = Arc::new(Int32Array::from(vec![Some(3), Some(4)]));
    let offsets = [0, 0, 1].into_iter().collect::<ScalarBuffer<i32>>();
    let type_ids = [84, 42, 84].into_iter().collect::<ScalarBuffer<i8>>();

    let expected =
        UnionArray::try_new(union_fields, type_ids, Some(offsets), vec![ints, strings]).unwrap();

    assert_eq!(array.to_data(), expected.to_data());
}

#[test]
fn test_binary_fixed_sized_offsets() {
    let array =
        FixedSizeBinaryArray::try_from_iter(vec![vec![0, 0], vec![0, 1], vec![0, 2]].into_iter())
            .expect("Failed to create FixedSizeBinaryArray from iterable");
    let array = array.slice(1, 2).into_data();
    // = [[0, 1], [0, 2]] due to the offset = 1

    let arrays = vec![&array];

    let mut mutable = MutableArrayData::new(arrays, false, 0);

    mutable.extend(0, 1, 2);
    mutable.extend(0, 0, 1);

    let result = mutable.freeze();
    let result = FixedSizeBinaryArray::from(result);

    let expected = FixedSizeBinaryArray::try_from_iter(vec![vec![0, 2], vec![0, 1]].into_iter())
        .expect("Failed to create FixedSizeBinaryArray from iterable");
    assert_eq!(result, expected);
}

#[test]
fn test_list_append() {
    let mut builder = ListBuilder::<Int64Builder>::new(Int64Builder::with_capacity(24));
    builder.values().append_slice(&[1, 2, 3]);
    builder.append(true);
    builder.values().append_slice(&[4, 5]);
    builder.append(true);
    builder.values().append_slice(&[6, 7, 8]);
    builder.values().append_slice(&[9, 10, 11]);
    builder.append(true);
    let a = builder.finish().into_data();

    let a_builder = Int64Builder::with_capacity(24);
    let mut a_builder = ListBuilder::<Int64Builder>::new(a_builder);
    a_builder.values().append_slice(&[12, 13]);
    a_builder.append(true);
    a_builder.append(true);
    a_builder.values().append_slice(&[14, 15]);
    a_builder.append(true);
    let b = a_builder.finish().into_data();

    let c = b.slice(1, 2);

    let mut mutable = MutableArrayData::new(vec![&a, &b, &c], false, 1);
    mutable.extend(0, 0, a.len());
    mutable.extend(1, 0, b.len());
    mutable.extend(2, 0, c.len());

    let finished = mutable.freeze();

    let expected_int_array = Int64Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
        Some(6),
        Some(7),
        Some(8),
        Some(9),
        Some(10),
        Some(11),
        // append first array
        Some(12),
        Some(13),
        Some(14),
        Some(15),
        // append second array
        Some(14),
        Some(15),
    ]);
    let list_value_offsets = Buffer::from_slice_ref([0i32, 3, 5, 11, 13, 13, 15, 15, 17]);
    let expected_list_data = ArrayData::try_new(
        DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
        8,
        None,
        0,
        vec![list_value_offsets],
        vec![expected_int_array.into_data()],
    )
    .unwrap();
    assert_eq!(finished, expected_list_data);
}

#[test]
fn test_list_nulls_append() {
    let mut builder = ListBuilder::<Int64Builder>::new(Int64Builder::with_capacity(32));
    builder.values().append_slice(&[1, 2, 3]);
    builder.append(true);
    builder.values().append_slice(&[4, 5]);
    builder.append(true);
    builder.append(false);
    builder.values().append_slice(&[6, 7, 8]);
    builder.values().append_null();
    builder.values().append_null();
    builder.values().append_slice(&[9, 10, 11]);
    builder.append(true);
    let a = builder.finish().into_data();

    let mut builder = ListBuilder::<Int64Builder>::new(Int64Builder::with_capacity(32));
    builder.values().append_slice(&[12, 13]);
    builder.append(true);
    builder.append(false);
    builder.append(true);
    builder.values().append_null();
    builder.values().append_null();
    builder.values().append_slice(&[14, 15]);
    builder.append(true);
    let b = builder.finish().into_data();
    let c = b.slice(1, 2);
    let d = b.slice(2, 2);

    let mut mutable = MutableArrayData::new(vec![&a, &b, &c, &d], false, 10);

    mutable.extend(0, 0, a.len());
    mutable.extend(1, 0, b.len());
    mutable.extend(2, 0, c.len());
    mutable.extend(3, 0, d.len());
    let result = mutable.freeze();

    let expected_int_array = Int64Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
        Some(6),
        Some(7),
        Some(8),
        None,
        None,
        Some(9),
        Some(10),
        Some(11),
        // second array
        Some(12),
        Some(13),
        None,
        None,
        Some(14),
        Some(15),
        // slice(1, 2) results in no values added
        None,
        None,
        Some(14),
        Some(15),
    ]);
    let list_value_offsets =
        Buffer::from_slice_ref([0, 3, 5, 5, 13, 15, 15, 15, 19, 19, 19, 19, 23]);
    let expected_list_data = ArrayData::try_new(
        DataType::List(Arc::new(Field::new("item", DataType::Int64, true))),
        12,
        Some(Buffer::from(&[0b11011011, 0b1110])),
        0,
        vec![list_value_offsets],
        vec![expected_int_array.into_data()],
    )
    .unwrap();
    assert_eq!(result, expected_list_data);
}

#[test]
fn test_map_nulls_append() {
    let mut builder = MapBuilder::<Int64Builder, Int64Builder>::new(
        None,
        Int64Builder::with_capacity(32),
        Int64Builder::with_capacity(32),
    );
    builder.keys().append_slice(&[1, 2, 3]);
    builder.values().append_slice(&[1, 2, 3]);
    builder.append(true).unwrap();
    builder.keys().append_slice(&[4, 5]);
    builder.values().append_slice(&[4, 5]);
    builder.append(true).unwrap();
    builder.append(false).unwrap();
    builder.keys().append_slice(&[6, 7, 8, 100, 101, 9, 10, 11]);
    builder.values().append_slice(&[6, 7, 8]);
    builder.values().append_null();
    builder.values().append_null();
    builder.values().append_slice(&[9, 10, 11]);
    builder.append(true).unwrap();

    let a = builder.finish().into_data();

    let mut builder = MapBuilder::<Int64Builder, Int64Builder>::new(
        None,
        Int64Builder::with_capacity(32),
        Int64Builder::with_capacity(32),
    );

    builder.keys().append_slice(&[12, 13]);
    builder.values().append_slice(&[12, 13]);
    builder.append(true).unwrap();
    builder.append(false).unwrap();
    builder.append(true).unwrap();
    builder.keys().append_slice(&[100, 101, 14, 15]);
    builder.values().append_null();
    builder.values().append_null();
    builder.values().append_slice(&[14, 15]);
    builder.append(true).unwrap();

    let b = builder.finish().into_data();
    let c = b.slice(1, 2);
    let d = b.slice(2, 2);

    let mut mutable = MutableArrayData::new(vec![&a, &b, &c, &d], false, 10);

    mutable.extend(0, 0, a.len());
    mutable.extend(1, 0, b.len());
    mutable.extend(2, 0, c.len());
    mutable.extend(3, 0, d.len());
    let result = mutable.freeze();

    let expected_key_array = Int64Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
        Some(6),
        Some(7),
        Some(8),
        Some(100),
        Some(101),
        Some(9),
        Some(10),
        Some(11),
        // second array
        Some(12),
        Some(13),
        Some(100),
        Some(101),
        Some(14),
        Some(15),
        // slice(1, 2) results in no values added
        Some(100),
        Some(101),
        Some(14),
        Some(15),
    ]);

    let expected_value_array = Int64Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
        Some(6),
        Some(7),
        Some(8),
        None,
        None,
        Some(9),
        Some(10),
        Some(11),
        // second array
        Some(12),
        Some(13),
        None,
        None,
        Some(14),
        Some(15),
        // slice(1, 2) results in no values added
        None,
        None,
        Some(14),
        Some(15),
    ]);

    let expected_entry_array = StructArray::from(vec![
        (
            Arc::new(Field::new("keys", DataType::Int64, false)),
            Arc::new(expected_key_array) as ArrayRef,
        ),
        (
            Arc::new(Field::new("values", DataType::Int64, true)),
            Arc::new(expected_value_array) as ArrayRef,
        ),
    ]);

    let map_offsets = Buffer::from_slice_ref([0, 3, 5, 5, 13, 15, 15, 15, 19, 19, 19, 19, 23]);

    let expected_list_data = ArrayData::try_new(
        DataType::Map(
            Arc::new(Field::new(
                "entries",
                DataType::Struct(Fields::from(vec![
                    Field::new("keys", DataType::Int64, false),
                    Field::new("values", DataType::Int64, true),
                ])),
                false,
            )),
            false,
        ),
        12,
        Some(Buffer::from(&[0b11011011, 0b1110])),
        0,
        vec![map_offsets],
        vec![expected_entry_array.into_data()],
    )
    .unwrap();
    assert_eq!(result, expected_list_data);
}

#[test]
fn test_map_keys_values_append() {
    let mut builder = MapBuilder::<Int64Builder, Int64Builder>::new(
        None,
        Int64Builder::with_capacity(32),
        Int64Builder::with_capacity(32),
    );
    let (keys, values) = builder.entries();
    keys.append_slice(&[1, 2, 3]);
    values.append_slice(&[1, 3, 4]);
    builder.append(true).unwrap();

    let (keys, values) = builder.entries();
    keys.append_slice(&[4, 5]);
    values.append_slice(&[4, 6]);
    builder.append(true).unwrap();

    builder.append(false).unwrap();

    let map = builder.finish();
    assert!(map.is_null(2));

    let first = map.value(0);
    let keys = first
        .column(0)
        .as_any()
        .downcast_ref::<Int64Array>()
        .unwrap();
    let values = first
        .column(1)
        .as_any()
        .downcast_ref::<Int64Array>()
        .unwrap();
    assert_eq!(keys, &Int64Array::from(vec![Some(1), Some(2), Some(3)]));
    assert_eq!(values, &Int64Array::from(vec![Some(1), Some(3), Some(4)]));

    let second = map.value(1);
    let keys = second
        .column(0)
        .as_any()
        .downcast_ref::<Int64Array>()
        .unwrap();
    let values = second
        .column(1)
        .as_any()
        .downcast_ref::<Int64Array>()
        .unwrap();
    assert_eq!(keys, &Int64Array::from(vec![Some(4), Some(5)]));
    assert_eq!(values, &Int64Array::from(vec![Some(4), Some(6)]));
}

#[test]
fn test_list_of_strings_append() {
    // [["alpha", "beta", None]]
    let mut builder = ListBuilder::new(StringBuilder::new());
    builder.values().append_value("Hello");
    builder.values().append_value("Arrow");
    builder.values().append_null();
    builder.append(true);
    let a = builder.finish().into_data();

    // [["alpha", "beta"], [None], ["gamma", "delta", None]]
    let mut builder = ListBuilder::new(StringBuilder::new());
    builder.values().append_value("alpha");
    builder.values().append_value("beta");
    builder.append(true);
    builder.values().append_null();
    builder.append(true);
    builder.values().append_value("gamma");
    builder.values().append_value("delta");
    builder.values().append_null();
    builder.append(true);
    let b = builder.finish().into_data();

    let mut mutable = MutableArrayData::new(vec![&a, &b], false, 10);

    mutable.extend(0, 0, a.len());
    mutable.extend(1, 0, b.len());
    mutable.extend(1, 1, 3);
    mutable.extend(1, 0, 0);
    let result = mutable.freeze();

    let expected_string_array = StringArray::from(vec![
        // extend a[0..a.len()]
        // a[0]
        Some("Hello"),
        Some("Arrow"),
        None,
        // extend b[0..b.len()]
        // b[0]
        Some("alpha"),
        Some("beta"),
        // b[1]
        None,
        // b[2]
        Some("gamma"),
        Some("delta"),
        None,
        // extend b[1..3]
        // b[1]
        None,
        // b[2]
        Some("gamma"),
        Some("delta"),
        None,
        // extend b[0..0]
    ]);
    let list_value_offsets = Buffer::from_slice_ref([0, 3, 5, 6, 9, 10, 13]);
    let expected_list_data = ArrayData::try_new(
        DataType::List(Arc::new(Field::new("item", DataType::Utf8, true))),
        6,
        None,
        0,
        vec![list_value_offsets],
        vec![expected_string_array.into_data()],
    )
    .unwrap();
    assert_eq!(result, expected_list_data);
}

#[test]
fn test_fixed_size_binary_append() {
    let a = vec![Some(vec![1, 2]), Some(vec![3, 4]), Some(vec![5, 6])];
    let a = FixedSizeBinaryArray::try_from_sparse_iter_with_size(a.into_iter(), 2)
        .expect("Failed to create FixedSizeBinaryArray from iterable")
        .into_data();

    let b = vec![
        None,
        Some(vec![7, 8]),
        Some(vec![9, 10]),
        None,
        Some(vec![13, 14]),
        None,
    ];
    let b = FixedSizeBinaryArray::try_from_sparse_iter_with_size(b.into_iter(), 2)
        .expect("Failed to create FixedSizeBinaryArray from iterable")
        .into_data();

    let mut mutable = MutableArrayData::new(vec![&a, &b], false, 10);

    mutable.extend(0, 0, a.len());
    mutable.extend(1, 0, b.len());
    mutable.extend(1, 1, 4);
    mutable.extend(1, 2, 3);
    mutable.extend(1, 5, 5);
    let result = mutable.freeze();

    let expected = vec![
        // a
        Some(vec![1, 2]),
        Some(vec![3, 4]),
        Some(vec![5, 6]),
        // b
        None,
        Some(vec![7, 8]),
        Some(vec![9, 10]),
        None,
        Some(vec![13, 14]),
        None,
        // b[1..4]
        Some(vec![7, 8]),
        Some(vec![9, 10]),
        None,
        // b[2..3]
        Some(vec![9, 10]),
        // b[4..4]
    ];
    let expected = FixedSizeBinaryArray::try_from_sparse_iter_with_size(expected.into_iter(), 2)
        .expect("Failed to create FixedSizeBinaryArray from iterable")
        .into_data();
    assert_eq!(result, expected);
}

#[test]
fn test_extend_nulls() {
    let int = Int32Array::from(vec![1, 2, 3, 4]).into_data();
    let mut mutable = MutableArrayData::new(vec![&int], true, 4);
    mutable.extend(0, 2, 3);
    mutable.extend_nulls(2);

    let data = mutable.freeze();
    data.validate_full().unwrap();
    let out = Int32Array::from(data);

    assert_eq!(out.null_count(), 2);
    assert_eq!(out.iter().collect::<Vec<_>>(), vec![Some(3), None, None]);
}

#[test]
#[should_panic(expected = "MutableArrayData not nullable")]
fn test_extend_nulls_panic() {
    let int = Int32Array::from(vec![1, 2, 3, 4]).into_data();
    let mut mutable = MutableArrayData::new(vec![&int], false, 4);
    mutable.extend_nulls(2);
}

#[test]
fn test_string_view() {
    let a1 =
        StringViewArray::from(vec!["foo", "very long string over 12 bytes", "bar"]).into_data();
    let a2 = StringViewArray::from_iter(vec![
        Some("bar"),
        None,
        Some("long string also over 12 bytes"),
    ])
    .into_data();

    a1.validate_full().unwrap();
    a2.validate_full().unwrap();

    let mut mutable = MutableArrayData::new(vec![&a1, &a2], false, 4);
    mutable.extend(1, 0, 1);
    mutable.extend(0, 1, 2);
    mutable.extend(0, 0, 1);
    mutable.extend(1, 2, 3);

    let array = StringViewArray::from(mutable.freeze());
    assert_eq!(array.data_buffers().len(), 2);
    // Should have reused data buffers
    assert_eq!(array.data_buffers()[0].as_ptr(), a1.buffers()[1].as_ptr());
    assert_eq!(array.data_buffers()[1].as_ptr(), a2.buffers()[1].as_ptr());

    let v = array.iter().collect::<Vec<_>>();
    assert_eq!(
        v,
        vec![
            Some("bar"),
            Some("very long string over 12 bytes"),
            Some("foo"),
            Some("long string also over 12 bytes")
        ]
    )
}

#[test]
#[should_panic(expected = "Arrays with inconsistent types passed to MutableArrayData")]
fn test_mixed_types() {
    let a = StringArray::from(vec!["abc", "def"]).to_data();
    let b = Int32Array::from(vec![1, 2, 3]).to_data();
    MutableArrayData::new(vec![&a, &b], false, 4);
}

#[test]
fn test_fixed_size_list_append() {
    let int_builder = UInt16Builder::with_capacity(64);
    let mut builder = FixedSizeListBuilder::<UInt16Builder>::new(int_builder, 2);
    builder.values().append_slice(&[1, 2]);
    builder.append(true);
    builder.values().append_slice(&[3, 4]);
    builder.append(false);
    builder.values().append_slice(&[5, 6]);
    builder.append(true);
    let a = builder.finish().into_data();

    let a_builder = UInt16Builder::with_capacity(64);
    let mut a_builder = FixedSizeListBuilder::<UInt16Builder>::new(a_builder, 2);
    a_builder.values().append_slice(&[7, 8]);
    a_builder.append(true);
    a_builder.values().append_slice(&[9, 10]);
    a_builder.append(true);
    a_builder.values().append_slice(&[11, 12]);
    a_builder.append(false);
    a_builder.values().append_slice(&[13, 14]);
    a_builder.append(true);
    a_builder.values().append_null();
    a_builder.values().append_null();
    a_builder.append(true);
    let b = a_builder.finish().into_data();

    let mut mutable = MutableArrayData::new(vec![&a, &b], false, 10);
    mutable.extend(0, 0, a.len());
    mutable.extend(1, 0, b.len());

    // append array
    mutable.extend(1, 1, 4);
    mutable.extend(1, 2, 3);

    let finished = mutable.freeze();

    let expected_int_array = UInt16Array::from(vec![
        Some(1),
        Some(2),
        Some(3),
        Some(4),
        Some(5),
        Some(6),
        // append first array
        Some(7),
        Some(8),
        Some(9),
        Some(10),
        Some(11),
        Some(12),
        Some(13),
        Some(14),
        None,
        None,
        // append slice(1, 3)
        Some(9),
        Some(10),
        Some(11),
        Some(12),
        Some(13),
        Some(14),
        // append slice(2, 1)
        Some(11),
        Some(12),
    ]);
    let expected_fixed_size_list_data = ArrayData::try_new(
        DataType::FixedSizeList(Arc::new(Field::new("item", DataType::UInt16, true)), 2),
        12,
        Some(Buffer::from(&[0b11011101, 0b101])),
        0,
        vec![],
        vec![expected_int_array.to_data()],
    )
    .unwrap();
    assert_eq!(finished, expected_fixed_size_list_data);
}
