# 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.

"""Integration tests for log (append-only) table operations.

Mirrors the Rust integration tests in crates/fluss/tests/integration/log_table.rs.
"""

import asyncio
import time

import pyarrow as pa
import pytest
from conftest import (
    assert_complex_edge,
    assert_complex_full,
    complex_column_names,
    complex_edge_row,
    complex_full_row,
    complex_null_row,
    complex_schema,
)

import fluss


async def test_append_and_scan(connection, admin):
    """Test appending record batches and scanning with a record-based scanner."""
    table_path = fluss.TablePath("fluss", "py_test_append_and_scan")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("c1", pa.int32()), pa.field("c2", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema, bucket_count=3, bucket_keys=["c1"])
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    batch1 = pa.RecordBatch.from_arrays(
        [pa.array([1, 2, 3], type=pa.int32()), pa.array(["a1", "a2", "a3"])],
        schema=pa.schema([pa.field("c1", pa.int32()), pa.field("c2", pa.string())]),
    )
    append_writer.write_arrow_batch(batch1)

    batch2 = pa.RecordBatch.from_arrays(
        [pa.array([4, 5, 6], type=pa.int32()), pa.array(["a4", "a5", "a6"])],
        schema=pa.schema([pa.field("c1", pa.int32()), pa.field("c2", pa.string())]),
    )
    append_writer.write_arrow_batch(batch2)

    await append_writer.flush()

    # Scan with record-based scanner
    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    records = await _poll_records(scanner, expected_count=6)

    assert len(records) == 6, f"Expected 6 records, got {len(records)}"

    records.sort(key=lambda r: r.row["c1"])

    expected_c1 = [1, 2, 3, 4, 5, 6]
    expected_c2 = ["a1", "a2", "a3", "a4", "a5", "a6"]
    for i, record in enumerate(records):
        assert record.row["c1"] == expected_c1[i], f"c1 mismatch at row {i}"
        assert record.row["c2"] == expected_c2[i], f"c2 mismatch at row {i}"

    # Test unsubscribe
    scanner.unsubscribe(bucket_id=0)

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_append_dict_rows(connection, admin):
    """Test appending rows as dicts and scanning."""
    table_path = fluss.TablePath("fluss", "py_test_append_dict_rows")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    # Append using dicts
    append_writer.append({"id": 1, "name": "Alice"})
    append_writer.append({"id": 2, "name": "Bob"})
    # Append using lists
    append_writer.append([3, "Charlie"])
    await append_writer.flush()

    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    records = await _poll_records(scanner, expected_count=3)
    assert len(records) == 3

    rows = sorted([r.row for r in records], key=lambda r: r["id"])
    assert rows[0] == {"id": 1, "name": "Alice"}
    assert rows[1] == {"id": 2, "name": "Bob"}
    assert rows[2] == {"id": 3, "name": "Charlie"}

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_list_offsets(connection, admin, wait_for_table_ready):
    """Test listing earliest, latest, and timestamp-based offsets."""
    table_path = fluss.TablePath("fluss", "py_test_list_offsets")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    await wait_for_table_ready(table_path)

    # Earliest offset should be 0 for empty table
    earliest = await admin.list_offsets(
        table_path, bucket_ids=[0], offset_spec=fluss.OffsetSpec.earliest()
    )
    assert earliest[0] == 0

    # Latest offset should be 0 for empty table
    latest = await admin.list_offsets(
        table_path, bucket_ids=[0], offset_spec=fluss.OffsetSpec.latest()
    )
    assert latest[0] == 0

    before_append_ms = int(time.time() * 1000)

    # Append some records
    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()
    batch = pa.RecordBatch.from_arrays(
        [
            pa.array([1, 2, 3], type=pa.int32()),
            pa.array(["alice", "bob", "charlie"]),
        ],
        schema=pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())]),
    )
    append_writer.write_arrow_batch(batch)
    await append_writer.flush()

    await asyncio.sleep(1)

    after_append_ms = int(time.time() * 1000)

    # Latest offset should be 3 after appending 3 records
    latest_after = await admin.list_offsets(
        table_path, bucket_ids=[0], offset_spec=fluss.OffsetSpec.latest()
    )
    assert latest_after[0] == 3

    # Earliest offset should still be 0
    earliest_after = await admin.list_offsets(
        table_path, bucket_ids=[0], offset_spec=fluss.OffsetSpec.earliest()
    )
    assert earliest_after[0] == 0

    # Timestamp before append should resolve to offset 0
    ts_before = await admin.list_offsets(
        table_path,
        bucket_ids=[0],
        offset_spec=fluss.OffsetSpec.timestamp(before_append_ms),
    )
    assert ts_before[0] == 0

    # Intentional sleep to avoid race condition FlussError(code=38) The timestamp is invalid
    await asyncio.sleep(1)

    # Timestamp after append should resolve to offset 3
    ts_after = await admin.list_offsets(
        table_path,
        bucket_ids=[0],
        offset_spec=fluss.OffsetSpec.timestamp(after_append_ms),
    )
    assert ts_after[0] == 3

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_project(connection, admin):
    """Test column projection by name and by index."""
    table_path = fluss.TablePath("fluss", "py_test_project")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema(
            [
                pa.field("col_a", pa.int32()),
                pa.field("col_b", pa.string()),
                pa.field("col_c", pa.int32()),
            ]
        )
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    batch = pa.RecordBatch.from_arrays(
        [
            pa.array([1, 2, 3], type=pa.int32()),
            pa.array(["x", "y", "z"]),
            pa.array([10, 20, 30], type=pa.int32()),
        ],
        schema=pa.schema(
            [
                pa.field("col_a", pa.int32()),
                pa.field("col_b", pa.string()),
                pa.field("col_c", pa.int32()),
            ]
        ),
    )
    append_writer.write_arrow_batch(batch)
    await append_writer.flush()

    # Test project_by_name: select col_b and col_c only
    scan = table.new_scan().project_by_name(["col_b", "col_c"])
    scanner = await scan.create_log_scanner()
    scanner.subscribe_buckets({0: 0})

    records = await _poll_records(scanner, expected_count=3)
    assert len(records) == 3

    records.sort(key=lambda r: r.row["col_c"])
    expected_col_b = ["x", "y", "z"]
    expected_col_c = [10, 20, 30]
    for i, record in enumerate(records):
        assert record.row["col_b"] == expected_col_b[i]
        assert record.row["col_c"] == expected_col_c[i]
        # col_a should not be present in projected results
        assert "col_a" not in record.row

    # Test project by indices [1, 0] -> (col_b, col_a)
    scanner2 = await table.new_scan().project([1, 0]).create_log_scanner()
    scanner2.subscribe_buckets({0: 0})

    records2 = await _poll_records(scanner2, expected_count=3)
    assert len(records2) == 3

    records2.sort(key=lambda r: r.row["col_a"])
    for i, record in enumerate(records2):
        assert record.row["col_b"] == expected_col_b[i]
        assert record.row["col_a"] == [1, 2, 3][i]
        assert "col_c" not in record.row

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_project_compound_types(connection, admin):
    """Projection selects and reorders ROW/MAP/ARRAY columns and drops others
    (mirrors the Rust projection_with_compound_types IT)."""
    table_path = fluss.TablePath("fluss", "py_test_project_compound")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema(
            [
                pa.field("id", pa.int32()),
                pa.field(
                    "nested", pa.struct([("seq", pa.int32()), ("label", pa.string())])
                ),
                pa.field("attrs", pa.map_(pa.string(), pa.int32())),
                pa.field("tags", pa.list_(pa.string())),
                pa.field("extra", pa.string()),
            ]
        )
    )
    await admin.create_table(
        table_path, fluss.TableDescriptor(schema), ignore_if_exists=False
    )
    table = await connection.get_table(table_path)

    aw = table.new_append().create_writer()
    aw.append(
        {
            "id": 7,
            "nested": {"seq": 42, "label": "hello"},
            "attrs": {"x": 1, "y": 2},
            "tags": ["alpha", "beta"],
            "extra": "ignore-me",
        }
    )
    await aw.flush()

    # Reorder and drop `extra`.
    scan = table.new_scan().project_by_name(["nested", "attrs", "tags", "id"])
    scanner = await scan.create_log_scanner()
    scanner.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
    records = await _poll_records(scanner, expected_count=1)
    assert len(records) == 1
    row = records[0].row
    assert row["nested"] == {"seq": 42, "label": "hello"}
    assert dict(row["attrs"]) == {"x": 1, "y": 2}
    assert row["tags"] == ["alpha", "beta"]
    assert row["id"] == 7
    assert "extra" not in row

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_poll_batches(connection, admin, wait_for_table_ready):
    """Test batch-based scanning with poll_arrow and poll_record_batch."""
    table_path = fluss.TablePath("fluss", "py_test_poll_batches")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    await wait_for_table_ready(table_path)

    table = await connection.get_table(table_path)
    scanner = await table.new_scan().create_record_batch_log_scanner()
    scanner.subscribe(bucket_id=0, start_offset=0)

    # Empty table should return empty result
    result = await scanner.poll_arrow(500)
    assert result.num_rows == 0

    writer = table.new_append().create_writer()
    pa_schema = pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [pa.array([1, 2], type=pa.int32()), pa.array(["a", "b"])],
            schema=pa_schema,
        )
    )
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [pa.array([3, 4], type=pa.int32()), pa.array(["c", "d"])],
            schema=pa_schema,
        )
    )
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [pa.array([5, 6], type=pa.int32()), pa.array(["e", "f"])],
            schema=pa_schema,
        )
    )
    await writer.flush()

    # Poll until we get all 6 records
    all_ids = await _poll_arrow_ids(scanner, expected_count=6)
    assert all_ids == [1, 2, 3, 4, 5, 6]

    # Append more and verify offset continuation (no duplicates)
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [pa.array([7, 8], type=pa.int32()), pa.array(["g", "h"])],
            schema=pa_schema,
        )
    )
    await writer.flush()

    new_ids = await _poll_arrow_ids(scanner, expected_count=2)
    assert new_ids == [7, 8]

    # Subscribe from mid-offset should truncate (skip earlier records)
    trunc_scanner = await table.new_scan().create_record_batch_log_scanner()
    trunc_scanner.subscribe(bucket_id=0, start_offset=3)

    trunc_ids = await _poll_arrow_ids(trunc_scanner, expected_count=5)
    assert trunc_ids == [4, 5, 6, 7, 8]

    # Projection with batch scanner
    proj_scanner = (
        await table.new_scan().project_by_name(["id"]).create_record_batch_log_scanner()
    )
    proj_scanner.subscribe(bucket_id=0, start_offset=0)
    batches = await proj_scanner.poll_record_batch(10000)
    assert len(batches) > 0
    assert batches[0].batch.num_columns == 1

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_to_arrow_and_to_pandas(connection, admin):
    """Test to_arrow() and to_pandas() convenience methods."""
    table_path = fluss.TablePath("fluss", "py_test_to_arrow_pandas")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    pa_schema = pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [pa.array([1, 2, 3], type=pa.int32()), pa.array(["a", "b", "c"])],
            schema=pa_schema,
        )
    )
    await writer.flush()

    num_buckets = (await admin.get_table_info(table_path)).num_buckets

    # to_arrow()
    scanner = await table.new_scan().create_record_batch_log_scanner()
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})
    arrow_table = await scanner.to_arrow()
    assert arrow_table.num_rows == 3
    assert arrow_table.schema.names == ["id", "name"]

    # to_pandas()
    scanner2 = await table.new_scan().create_record_batch_log_scanner()
    scanner2.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})
    df = await scanner2.to_pandas()
    assert len(df) == 3
    assert list(df.columns) == ["id", "name"]

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_to_arrow_batch_reader(connection, admin):
    """Test to_arrow_batch_reader() returns a lazy PyArrow RecordBatchReader."""
    table_path = fluss.TablePath("fluss", "py_test_to_arrow_batch_reader")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    pa_schema = pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [pa.array([10, 20, 30], type=pa.int32()), pa.array(["x", "y", "z"])],
            schema=pa_schema,
        )
    )
    await writer.flush()

    num_buckets = (await admin.get_table_info(table_path)).num_buckets

    scanner = await table.new_scan().create_record_batch_log_scanner()
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    # to_arrow_batch_reader() is a blocking/sync API; run in a thread to
    # avoid starving the asyncio event loop (see docstring warning).
    def _read_all():
        reader = scanner.to_arrow_batch_reader()
        assert isinstance(reader, pa.RecordBatchReader)
        assert reader.schema == pa_schema

        batches = list(reader)
        total_rows = sum(b.num_rows for b in batches)
        assert total_rows == 3

        result_table = pa.Table.from_batches(batches, schema=pa_schema)
        assert result_table.column("id").to_pylist() == [10, 20, 30]
        assert result_table.column("name").to_pylist() == ["x", "y", "z"]

    await asyncio.to_thread(_read_all)

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_to_arrow_batch_reader_drop_and_guard(connection, admin):
    """Test reader-active guard and Drop cleanup on mid-iteration drop."""
    table_path = fluss.TablePath("fluss", "py_test_batch_reader_drop_guard")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    pa_schema = pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    # Write multiple separate flushes so the server stores multiple log
    # batches per bucket. This makes it likely that the reader's first poll
    # only drains a subset, leaving real work for the Drop cleanup loop.
    num_flushes = 10
    rows_per_flush = 200
    total_rows = num_flushes * rows_per_flush
    for f in range(num_flushes):
        start = f * rows_per_flush
        writer.write_arrow_batch(
            pa.RecordBatch.from_arrays(
                [
                    pa.array(
                        list(range(start, start + rows_per_flush)), type=pa.int32()
                    ),
                    pa.array(
                        [f"row_{i}" for i in range(start, start + rows_per_flush)]
                    ),
                ],
                schema=pa_schema,
            )
        )
        await writer.flush()

    num_buckets = (await admin.get_table_info(table_path)).num_buckets

    scanner = await table.new_scan().create_record_batch_log_scanner()
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    # to_arrow_batch_reader() is a blocking/sync API; run all blocking
    # interactions in a thread to avoid starving the asyncio event loop.
    def _test_guard_and_drop():
        # --- Guard blocks subscribe / unsubscribe while reader is active ---
        reader = scanner.to_arrow_batch_reader()
        with pytest.raises(fluss.FlussError, match="RecordBatchLogReader is active"):
            scanner.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
        with pytest.raises(fluss.FlussError, match="RecordBatchLogReader is active"):
            scanner.unsubscribe(0)

        # --- Drop mid-iteration: read one batch, then discard ---
        first_batch = next(reader)
        assert first_batch.num_rows > 0
        del reader

        # --- Drop unsubscribed leftover buckets: creating a reader without
        #     re-subscribing must fail with "No buckets subscribed" ---
        with pytest.raises(fluss.FlussError, match="No buckets subscribed"):
            scanner.to_arrow_batch_reader()

        # --- Guard cleared after drop: scanner is reusable from a fresh subscribe ---
        scanner.subscribe_buckets(
            {i: fluss.EARLIEST_OFFSET for i in range(num_buckets)}
        )
        reader2 = scanner.to_arrow_batch_reader()
        batches = list(reader2)
        assert sum(b.num_rows for b in batches) == total_rows

    await asyncio.to_thread(_test_guard_and_drop)

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_partitioned_table_append_scan(connection, admin, wait_for_table_ready):
    """Test append and scan on a partitioned log table."""
    table_path = fluss.TablePath("fluss", "py_test_partitioned_log_append")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema(
            [
                pa.field("id", pa.int32()),
                pa.field("region", pa.string()),
                pa.field("value", pa.int64()),
            ]
        )
    )
    table_descriptor = fluss.TableDescriptor(
        schema,
        partition_keys=["region"],
    )
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    # Create partitions
    for region in ["US", "EU"]:
        await admin.create_partition(
            table_path, {"region": region}, ignore_if_exists=True
        )
        await wait_for_table_ready(table_path, partition_name=region)
    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    # Append rows
    test_data = [
        (1, "US", 100),
        (2, "US", 200),
        (3, "EU", 300),
        (4, "EU", 400),
    ]
    for id_, region, value in test_data:
        append_writer.append({"id": id_, "region": region, "value": value})
    await append_writer.flush()

    # Append arrow batches per partition
    pa_schema = pa.schema(
        [
            pa.field("id", pa.int32()),
            pa.field("region", pa.string()),
            pa.field("value", pa.int64()),
        ]
    )
    us_batch = pa.RecordBatch.from_arrays(
        [
            pa.array([5, 6], type=pa.int32()),
            pa.array(["US", "US"]),
            pa.array([500, 600], type=pa.int64()),
        ],
        schema=pa_schema,
    )
    append_writer.write_arrow_batch(us_batch)

    eu_batch = pa.RecordBatch.from_arrays(
        [
            pa.array([7, 8], type=pa.int32()),
            pa.array(["EU", "EU"]),
            pa.array([700, 800], type=pa.int64()),
        ],
        schema=pa_schema,
    )
    append_writer.write_arrow_batch(eu_batch)
    await append_writer.flush()

    # Verify partition offsets
    us_offsets = await admin.list_partition_offsets(
        table_path,
        partition_name="US",
        bucket_ids=[0],
        offset_spec=fluss.OffsetSpec.latest(),
    )
    assert us_offsets[0] == 4, "US partition should have 4 records"

    eu_offsets = await admin.list_partition_offsets(
        table_path,
        partition_name="EU",
        bucket_ids=[0],
        offset_spec=fluss.OffsetSpec.latest(),
    )
    assert eu_offsets[0] == 4, "EU partition should have 4 records"

    # Scan all partitions
    scanner = await table.new_scan().create_log_scanner()
    partition_infos = await admin.list_partition_infos(table_path)
    for p in partition_infos:
        scanner.subscribe_partition(
            partition_id=p.partition_id, bucket_id=0, start_offset=0
        )

    expected = [
        (1, "US", 100),
        (2, "US", 200),
        (3, "EU", 300),
        (4, "EU", 400),
        (5, "US", 500),
        (6, "US", 600),
        (7, "EU", 700),
        (8, "EU", 800),
    ]

    # Poll and verify per-bucket grouping
    all_records = []
    deadline = time.monotonic() + 10
    while len(all_records) < 8 and time.monotonic() < deadline:
        scan_records = await scanner.poll(5000)
        for bucket, bucket_records in scan_records.items():
            assert bucket.partition_id is not None, (
                "Partitioned table should have partition_id"
            )
            # All records in a bucket should belong to the same partition
            regions = {r.row["region"] for r in bucket_records}
            assert len(regions) == 1, f"Bucket has mixed regions: {regions}"
            all_records.extend(bucket_records)

    assert len(all_records) == 8

    collected = sorted(
        [(r.row["id"], r.row["region"], r.row["value"]) for r in all_records],
        key=lambda x: x[0],
    )
    assert collected == expected

    # Test unsubscribe_partition: unsubscribe from EU, only US data should remain
    unsub_scanner = await table.new_scan().create_log_scanner()
    eu_partition_id = next(
        p.partition_id for p in partition_infos if p.partition_name == "EU"
    )
    for p in partition_infos:
        unsub_scanner.subscribe_partition(p.partition_id, 0, 0)
    unsub_scanner.unsubscribe_partition(eu_partition_id, 0)

    remaining = await _poll_records(unsub_scanner, expected_count=4, timeout_s=5)
    assert len(remaining) == 4
    assert all(r.row["region"] == "US" for r in remaining)

    # Test subscribe_partition_buckets (batch subscribe)
    batch_scanner = await table.new_scan().create_log_scanner()
    partition_bucket_offsets = {
        (p.partition_id, 0): fluss.EARLIEST_OFFSET for p in partition_infos
    }
    batch_scanner.subscribe_partition_buckets(partition_bucket_offsets)

    batch_records = await _poll_records(batch_scanner, expected_count=8)
    assert len(batch_records) == 8
    batch_collected = sorted(
        [(r.row["id"], r.row["region"], r.row["value"]) for r in batch_records],
        key=lambda x: x[0],
    )
    assert batch_collected == expected

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_write_arrow(connection, admin):
    """Test writing a full PyArrow Table via write_arrow()."""
    table_path = fluss.TablePath("fluss", "py_test_write_arrow")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    pa_schema = pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    arrow_table = pa.table(
        {
            "id": pa.array([1, 2, 3, 4, 5], type=pa.int32()),
            "name": pa.array(["alice", "bob", "charlie", "dave", "eve"]),
        },
        schema=pa_schema,
    )
    writer.write_arrow(arrow_table)
    await writer.flush()

    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner = await table.new_scan().create_record_batch_log_scanner()
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    result = await scanner.to_arrow()
    assert result.num_rows == 5

    ids = sorted(result.column("id").to_pylist())
    names = [
        n
        for _, n in sorted(
            zip(result.column("id").to_pylist(), result.column("name").to_pylist())
        )
    ]
    assert ids == [1, 2, 3, 4, 5]
    assert names == ["alice", "bob", "charlie", "dave", "eve"]

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_write_pandas(connection, admin):
    """Test writing a Pandas DataFrame via write_pandas()."""
    import pandas as pd

    table_path = fluss.TablePath("fluss", "py_test_write_pandas")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("name", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    df = pd.DataFrame({"id": [10, 20, 30], "name": ["x", "y", "z"]})
    writer.write_pandas(df)
    await writer.flush()

    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner = await table.new_scan().create_record_batch_log_scanner()
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    result = await scanner.to_pandas()
    assert len(result) == 3

    result_sorted = result.sort_values("id").reset_index(drop=True)
    assert result_sorted["id"].tolist() == [10, 20, 30]
    assert result_sorted["name"].tolist() == ["x", "y", "z"]

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_partitioned_table_to_arrow(connection, admin, wait_for_table_ready):
    """Test to_arrow() on partitioned tables."""
    table_path = fluss.TablePath("fluss", "py_test_partitioned_to_arrow")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema(
            [
                pa.field("id", pa.int32()),
                pa.field("region", pa.string()),
                pa.field("value", pa.int64()),
            ]
        )
    )
    table_descriptor = fluss.TableDescriptor(schema, partition_keys=["region"])
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    for region in ["US", "EU"]:
        await admin.create_partition(
            table_path, {"region": region}, ignore_if_exists=True
        )
        await wait_for_table_ready(table_path, partition_name=region)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()
    writer.append({"id": 1, "region": "US", "value": 100})
    writer.append({"id": 2, "region": "EU", "value": 200})
    await writer.flush()

    scanner = await table.new_scan().create_record_batch_log_scanner()
    partition_infos = await admin.list_partition_infos(table_path)
    for p in partition_infos:
        scanner.subscribe_partition(p.partition_id, 0, fluss.EARLIEST_OFFSET)

    arrow_table = await scanner.to_arrow()
    assert arrow_table.num_rows == 2

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_scan_records_indexing_and_slicing(connection, admin):
    """Test ScanRecords indexing, slicing (incl. negative steps), and iteration consistency."""
    table_path = fluss.TablePath("fluss", "py_test_scan_records_indexing")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("val", pa.string())])
    )
    await admin.create_table(table_path, fluss.TableDescriptor(schema))

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [
                pa.array(list(range(1, 9)), type=pa.int32()),
                pa.array([f"v{i}" for i in range(1, 9)]),
            ],
            schema=pa.schema(
                [pa.field("id", pa.int32()), pa.field("val", pa.string())]
            ),
        )
    )
    await writer.flush()

    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    # Poll until we get a non-empty ScanRecords (need ≥2 records for slice tests)
    sr = None
    deadline = time.monotonic() + 10
    while time.monotonic() < deadline:
        sr = await scanner.poll(5000)
        if len(sr) >= 2:
            break
    assert sr is not None and len(sr) >= 2, "Expected at least 2 records"
    n = len(sr)
    offsets = [sr[i].offset for i in range(n)]

    # Iteration and indexing must produce the same order
    assert [r.offset for r in sr] == offsets

    # Negative indexing
    assert sr[-1].offset == offsets[-1]
    assert sr[-n].offset == offsets[0]

    # Verify slices match the same operation on the offsets reference list
    test_slices = [
        slice(1, n - 1),  # forward subrange
        slice(None, None, -1),  # [::-1] full reverse
        slice(n - 2, 0, -1),  # reverse with bounds
        slice(n - 1, 0, -2),  # reverse with step
        slice(None, None, 2),  # [::2]
        slice(1, None, 3),  # [1::3]
        slice(2, 2),  # empty
    ]
    for s in test_slices:
        result = [r.offset for r in sr[s]]
        assert result == offsets[s], f"slice {s}: got {result}, expected {offsets[s]}"

    # Bucket-based indexing
    for bucket in sr.buckets():
        assert len(sr[bucket]) > 0

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_async_iterator(connection, admin):
    """Test the Python asynchronous iterator loop (`async for`) on LogScanner."""
    table_path = fluss.TablePath("fluss", "py_test_async_iterator")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("val", pa.string())])
    )
    await admin.create_table(table_path, fluss.TableDescriptor(schema))

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    # Write 5 records
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [
                pa.array(list(range(1, 6)), type=pa.int32()),
                pa.array([f"async{i}" for i in range(1, 6)]),
            ],
            schema=pa.schema(
                [pa.field("id", pa.int32()), pa.field("val", pa.string())]
            ),
        )
    )
    await writer.flush()

    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    collected = []

    # Here is the magical Issue #424 async iterator logic at work:
    async def consume_scanner():
        async for record in scanner:
            collected.append(record)
            if len(collected) == 5:
                break

    await consume_scanner()

    assert len(collected) == 5, f"Expected 5 records, got {len(collected)}"

    collected.sort(key=lambda r: r.row["id"])
    for i, record in enumerate(collected):
        assert record.row["id"] == i + 1
        assert record.row["val"] == f"async{i + 1}"

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_async_iterator_break_no_leak(connection, admin):
    """Verify that breaking out of `async for` does not leak resources.

    After breaking, the scanner must still be usable for synchronous
    `poll()` calls.  If the old implementation's tokio::spawn'd task
    were still alive, it would hold the Mutex and cause `poll()` to
    deadlock or error.
    """
    table_path = fluss.TablePath("fluss", "py_test_async_break_leak")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("val", pa.string())])
    )
    await admin.create_table(table_path, fluss.TableDescriptor(schema))

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [
                pa.array(list(range(1, 11)), type=pa.int32()),
                pa.array([f"v{i}" for i in range(1, 11)]),
            ],
            schema=pa.schema(
                [pa.field("id", pa.int32()), pa.field("val", pa.string())]
            ),
        )
    )
    await writer.flush()

    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    # Phase 1: async for with early break (collect only 3 of 10)
    collected_async = []

    async def consume_and_break():
        async for record in scanner:
            collected_async.append(record)
            if len(collected_async) >= 3:
                break

    await consume_and_break()
    assert len(collected_async) == 3, (
        f"Expected 3 records from async for, got {len(collected_async)}"
    )

    # Phase 2: sync poll() must still work — proves no leaked task / lock.
    # With small data and few buckets, _async_poll may have fetched all
    # records in one batch. After break, the un-yielded records from that
    # batch are lost. So sync poll may return 0 records — the key assertion
    # is that poll() completes without deadlock (returns within timeout).
    remaining = await scanner.poll(2000)
    assert remaining is not None, "poll() should return (not deadlock)"

    # If we got records, verify no duplicates
    async_ids = {r.row["id"] for r in collected_async}
    sync_ids = {r.row["id"] for r in remaining}
    assert async_ids.isdisjoint(sync_ids), (
        f"Duplicate IDs between async and sync: {async_ids & sync_ids}"
    )

    # All IDs must be from the original 1-10 range
    all_ids = async_ids | sync_ids
    assert all_ids.issubset(set(range(1, 11))), (
        f"Unexpected IDs: {all_ids - set(range(1, 11))}"
    )

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_async_iterator_multiple_batches(connection, admin):
    """Verify async iteration works across multiple network poll cycles.

    _async_poll does a single bounded poll per call.  Writing 20 records
    to multiple buckets ensures the Python generator must loop through
    several _async_poll calls to collect them all.
    """
    table_path = fluss.TablePath("fluss", "py_test_async_multi_batch")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("val", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema, bucket_count=3, bucket_keys=["id"])
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    num_records = 20
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [
                pa.array(list(range(1, num_records + 1)), type=pa.int32()),
                pa.array([f"multi{i}" for i in range(1, num_records + 1)]),
            ],
            schema=pa.schema(
                [pa.field("id", pa.int32()), pa.field("val", pa.string())]
            ),
        )
    )
    await writer.flush()

    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    collected = []

    async def consume_all():
        async for record in scanner:
            collected.append(record)
            if len(collected) >= num_records:
                break

    await consume_all()
    assert len(collected) == num_records, (
        f"Expected {num_records} records, got {len(collected)}"
    )

    # Verify all IDs are present (order may vary due to bucketing)
    ids = sorted(r.row["id"] for r in collected)
    assert ids == list(range(1, num_records + 1))

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_batch_async_iterator(connection, admin):
    """Test the Python asynchronous iterator loop (`async for`) on a batch LogScanner.

    With our __aiter__ dispatch, a batch-based scanner should yield RecordBatch
    objects (not ScanRecord). Each yielded item has .batch (PyArrow RecordBatch),
    .bucket, .base_offset, .last_offset.
    """
    table_path = fluss.TablePath("fluss", "py_test_batch_async_iter")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("val", pa.string())])
    )
    await admin.create_table(table_path, fluss.TableDescriptor(schema))

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [
                pa.array(list(range(1, 7)), type=pa.int32()),
                pa.array([f"bv{i}" for i in range(1, 7)]),
            ],
            schema=pa.schema(
                [pa.field("id", pa.int32()), pa.field("val", pa.string())]
            ),
        )
    )
    await writer.flush()

    batch_scanner = await table.new_scan().create_record_batch_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    batch_scanner.subscribe_buckets(
        {i: fluss.EARLIEST_OFFSET for i in range(num_buckets)}
    )

    collected_batches = []
    total_rows = 0

    async def consume_batches():
        nonlocal total_rows
        async for rb in batch_scanner:
            collected_batches.append(rb)
            total_rows += rb.batch.num_rows
            if total_rows >= 6:
                break

    await consume_batches()

    assert total_rows >= 6, f"Expected >=6 total rows, got {total_rows}"
    assert len(collected_batches) > 0

    # Verify each yielded item is a RecordBatch with expected attributes
    for rb in collected_batches:
        assert hasattr(rb, "batch"), "RecordBatch should have .batch"
        assert hasattr(rb, "bucket"), "RecordBatch should have .bucket"
        assert hasattr(rb, "base_offset"), "RecordBatch should have .base_offset"
        assert hasattr(rb, "last_offset"), "RecordBatch should have .last_offset"
        # .batch should be a PyArrow RecordBatch
        arrow_batch = rb.batch
        assert isinstance(arrow_batch, pa.RecordBatch), (
            f"Expected PyArrow RecordBatch, got {type(arrow_batch).__name__}"
        )
        assert arrow_batch.num_columns == 2
        assert set(arrow_batch.schema.names) == {"id", "val"}

    # Verify all 6 IDs are present
    all_ids = []
    for rb in collected_batches:
        all_ids.extend(rb.batch.column("id").to_pylist())
    assert sorted(all_ids[:6]) == [1, 2, 3, 4, 5, 6]

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_batch_async_iterator_break_no_leak(connection, admin):
    """Verify that breaking out of batch `async for` does not leak resources.

    After breaking, the scanner must still be usable for synchronous
    poll_record_batch() calls, proving no leaked task or lock.
    """
    table_path = fluss.TablePath("fluss", "py_test_batch_async_break")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("val", pa.string())])
    )
    await admin.create_table(table_path, fluss.TableDescriptor(schema))

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [
                pa.array(list(range(1, 11)), type=pa.int32()),
                pa.array([f"bl{i}" for i in range(1, 11)]),
            ],
            schema=pa.schema(
                [pa.field("id", pa.int32()), pa.field("val", pa.string())]
            ),
        )
    )
    await writer.flush()

    batch_scanner = await table.new_scan().create_record_batch_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    batch_scanner.subscribe_buckets(
        {i: fluss.EARLIEST_OFFSET for i in range(num_buckets)}
    )

    # Phase 1: async for with early break (collect just 1 batch)
    first_batch = None

    async def consume_and_break():
        nonlocal first_batch
        async for rb in batch_scanner:
            first_batch = rb
            break

    await consume_and_break()
    assert first_batch is not None, "Should have received at least 1 batch"
    assert first_batch.batch.num_rows > 0

    # Phase 2: sync poll_record_batch() must still work — proves no leak
    remaining = await batch_scanner.poll_record_batch(2000)
    assert remaining is not None, "poll_record_batch() should return (not deadlock)"

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_batch_async_iterator_multiple_batches(connection, admin):
    """Verify batch async iteration works across multiple network poll cycles.

    Writing 20 records to 3 buckets ensures the generator must loop through
    several _async_poll_batches calls to collect them all.
    """
    table_path = fluss.TablePath("fluss", "py_test_batch_async_multi")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = fluss.Schema(
        pa.schema([pa.field("id", pa.int32()), pa.field("val", pa.string())])
    )
    table_descriptor = fluss.TableDescriptor(schema, bucket_count=3, bucket_keys=["id"])
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    writer = table.new_append().create_writer()

    num_records = 20
    writer.write_arrow_batch(
        pa.RecordBatch.from_arrays(
            [
                pa.array(list(range(1, num_records + 1)), type=pa.int32()),
                pa.array([f"bm{i}" for i in range(1, num_records + 1)]),
            ],
            schema=pa.schema(
                [pa.field("id", pa.int32()), pa.field("val", pa.string())]
            ),
        )
    )
    await writer.flush()

    batch_scanner = await table.new_scan().create_record_batch_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    batch_scanner.subscribe_buckets(
        {i: fluss.EARLIEST_OFFSET for i in range(num_buckets)}
    )

    all_ids = []

    async def consume_all():
        async for rb in batch_scanner:
            all_ids.extend(rb.batch.column("id").to_pylist())
            if len(all_ids) >= num_records:
                break

    await consume_all()
    assert len(all_ids) >= num_records, (
        f"Expected >={num_records} IDs, got {len(all_ids)}"
    )
    assert sorted(all_ids[:num_records]) == list(range(1, num_records + 1))

    await admin.drop_table(table_path, ignore_if_not_exists=False)


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


async def _poll_records(scanner, expected_count, timeout_s=10):
    """Poll a record-based scanner until expected_count records are collected."""
    collected = []
    deadline = time.monotonic() + timeout_s
    while len(collected) < expected_count and time.monotonic() < deadline:
        records = await scanner.poll(5000)
        collected.extend(records)
    return collected


async def _poll_arrow_ids(scanner, expected_count, timeout_s=10):
    """Poll a batch scanner and extract 'id' column values."""
    all_ids = []
    deadline = time.monotonic() + timeout_s
    while len(all_ids) < expected_count and time.monotonic() < deadline:
        arrow_table = await scanner.poll_arrow(5000)
        if arrow_table.num_rows > 0:
            all_ids.extend(arrow_table.column("id").to_pylist())
    return all_ids


async def test_append_and_scan_with_array(connection, admin):
    """Test appending and scanning with array columns."""
    table_path = fluss.TablePath("fluss", "py_test_append_and_scan_with_array")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    pa_schema = pa.schema(
        [
            pa.field("id", pa.int32()),
            pa.field("tags", pa.list_(pa.string())),
            pa.field("scores", pa.list_(pa.int32())),
        ]
    )
    schema = fluss.Schema(pa_schema)
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    # Batch 1: Testing standard lists
    batch1 = pa.RecordBatch.from_arrays(
        [
            pa.array([1, 2], type=pa.int32()),
            pa.array([["a", "b"], ["c"]], type=pa.list_(pa.string())),
            pa.array([[10, 20], [30]], type=pa.list_(pa.int32())),
        ],
        schema=pa_schema,
    )
    append_writer.write_arrow_batch(batch1)

    # Batch 2: Testing null values inside arrays and null arrays
    batch2 = pa.RecordBatch.from_arrays(
        [
            pa.array([3, 4, 5, 6], type=pa.int32()),
            pa.array([["d", None], None, [], [None]], type=pa.list_(pa.string())),
            pa.array([[40, 50], [60], None, []], type=pa.list_(pa.int32())),
        ],
        schema=pa_schema,
    )
    append_writer.write_arrow_batch(batch2)
    await append_writer.flush()

    # Verify via LogScanner (record-by-record)
    scanner = await table.new_scan().create_log_scanner()
    scanner.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
    records = await _poll_records(scanner, expected_count=6)

    assert len(records) == 6
    records.sort(key=lambda r: r.row["id"])

    # Verify Batch 1
    assert records[0].row["tags"] == ["a", "b"]
    assert records[0].row["scores"] == [10, 20]
    assert records[1].row["tags"] == ["c"]
    assert records[1].row["scores"] == [30]

    # Verify Batch 2
    assert records[2].row["tags"] == ["d", None]
    assert records[2].row["scores"] == [40, 50]
    assert records[3].row["tags"] is None
    assert records[3].row["scores"] == [60]
    assert records[4].row["tags"] == []
    assert records[4].row["scores"] is None
    assert records[5].row["tags"] == [None]
    assert records[5].row["scores"] == []

    # Verify via to_arrow (batch-based)
    scanner2 = await table.new_scan().create_record_batch_log_scanner()
    scanner2.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
    result_table = await scanner2.to_arrow()

    assert result_table.num_rows == 6
    assert result_table.column("tags").to_pylist() == [
        ["a", "b"],
        ["c"],
        ["d", None],
        None,
        [],
        [None],
    ]
    assert result_table.column("scores").to_pylist() == [
        [10, 20],
        [30],
        [40, 50],
        [60],
        None,
        [],
    ]


async def test_append_rows_with_array(connection, admin):
    """Test appending rows with array data as Python lists and scanning."""
    table_path = fluss.TablePath("fluss", "py_test_append_rows_with_array")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    pa_schema = pa.schema(
        [
            pa.field("id", pa.int32()),
            pa.field("tags", pa.list_(pa.string())),
            pa.field("scores", pa.list_(pa.int32())),
        ]
    )
    schema = fluss.Schema(pa_schema)
    table_descriptor = fluss.TableDescriptor(schema)
    await admin.create_table(table_path, table_descriptor, ignore_if_exists=False)

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    # Append rows using dicts with lists
    append_writer.append({"id": 1, "tags": ["a", "b"], "scores": [10, 20]})
    append_writer.append({"id": 2, "tags": ["c"], "scores": [30]})
    # Append row using list with nested list (null handling)
    append_writer.append([3, None, [40, None, 60]])

    await append_writer.flush()

    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    records = await _poll_records(scanner, expected_count=3)
    assert len(records) == 3

    rows = sorted([r.row for r in records], key=lambda r: r["id"])
    assert rows[0] == {"id": 1, "tags": ["a", "b"], "scores": [10, 20]}
    assert rows[1] == {"id": 2, "tags": ["c"], "scores": [30]}
    # Note: records[2].row["tags"] will be None, records[2].row["scores"] will be [40, None, 60]
    assert rows[2]["id"] == 3
    assert rows[2]["tags"] is None
    assert rows[2]["scores"] == [40, None, 60]

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_append_rows_with_nested_array(connection, admin):
    """Test appending rows with nested array data (ARRAY<ARRAY<INT>>) and scanning."""
    table_path = fluss.TablePath("fluss", "py_test_append_rows_with_nested_array")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    pa_schema = pa.schema(
        [
            pa.field("id", pa.int32()),
            pa.field("matrix", pa.list_(pa.list_(pa.int32()))),
        ]
    )
    schema = fluss.Schema(pa_schema)
    await admin.create_table(
        table_path, fluss.TableDescriptor(schema), ignore_if_exists=False
    )

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    # Append nested lists
    append_writer.append({"id": 1, "matrix": [[1, 2], [3, 4]]})
    append_writer.append({"id": 2, "matrix": [[], [5], [6, 7, 8]]})
    append_writer.append({"id": 3, "matrix": None})
    append_writer.append({"id": 4, "matrix": [[1, None], None, []]})
    append_writer.append({"id": 5, "matrix": [[None, None]]})

    await append_writer.flush()

    scanner = await table.new_scan().create_log_scanner()
    num_buckets = (await admin.get_table_info(table_path)).num_buckets
    scanner.subscribe_buckets({i: fluss.EARLIEST_OFFSET for i in range(num_buckets)})

    records = await _poll_records(scanner, expected_count=5)
    assert len(records) == 5

    rows = sorted([r.row for r in records], key=lambda r: r["id"])
    assert rows[0] == {"id": 1, "matrix": [[1, 2], [3, 4]]}
    assert rows[1] == {"id": 2, "matrix": [[], [5], [6, 7, 8]]}
    assert rows[2] == {"id": 3, "matrix": None}
    assert rows[3] == {"id": 4, "matrix": [[1, None], None, []]}
    assert rows[4] == {"id": 5, "matrix": [[None, None]]}

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_append_rows_with_invalid_array(connection, admin):
    """Test that appending invalid data to an array column raises an error."""
    table_path = fluss.TablePath("fluss", "py_test_append_rows_with_invalid_array")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    pa_schema = pa.schema(
        [
            pa.field("id", pa.int32()),
            pa.field("tags", pa.list_(pa.string())),
        ]
    )
    schema = fluss.Schema(pa_schema)
    await admin.create_table(
        table_path, fluss.TableDescriptor(schema), ignore_if_exists=False
    )

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()

    # Appending a string instead of a list should raise an error
    with pytest.raises(Exception, match="Expected sequence for Array column"):
        append_writer.append({"id": 4, "tags": "not_a_list"})

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_all_complex_datatypes(connection, admin):
    """Comprehensive ARRAY/MAP/ROW coverage on a log table.

    Appends fully-populated, edge-case, and all-null rows (see complex_types.py)
    and verifies them through both the record (dict) scan path and the Arrow
    scan path -- the two paths must agree. Mirrors the section-based
    ``all_supported_datatypes`` structure of the Rust integration tests.
    """
    table_path = fluss.TablePath("fluss", "py_test_log_all_complex")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    schema = complex_schema()
    await admin.create_table(
        table_path, fluss.TableDescriptor(schema), ignore_if_exists=False
    )

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()
    append_writer.append(complex_full_row(1))
    append_writer.append(complex_edge_row(2))
    append_writer.append(complex_null_row(3))
    await append_writer.flush()

    # Record (dict) scan path.
    scanner = await table.new_scan().create_log_scanner()
    scanner.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
    records = await _poll_records(scanner, expected_count=3)
    assert len(records) == 3
    poll_rows = sorted([r.row for r in records], key=lambda r: r["id"])
    assert_complex_full(poll_rows[0])
    assert_complex_edge(poll_rows[1])
    for col in complex_column_names():
        assert poll_rows[2][col] is None

    # Arrow scan path: to_pylist() agrees with the dict path column-for-column,
    # except NaN-bearing float columns (NaN != NaN), which are checked elsewhere.
    scanner2 = await table.new_scan().create_record_batch_log_scanner()
    scanner2.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
    result_table = await scanner2.to_arrow()
    assert result_table.num_rows == 3
    arrow_rows = result_table.sort_by("id").to_pylist()
    float_cols = {"arr_float", "arr_double", "map_float", "map_double"}
    for i in range(3):
        for col in complex_column_names():
            if col in float_cols:
                continue
            assert arrow_rows[i][col] == poll_rows[i][col], (
                f"scan-path mismatch at row {i}, column {col}"
            )

    await admin.drop_table(table_path, ignore_if_not_exists=False)


async def test_append_arrow_batch_complex_types(connection, admin):
    """Arrow write path: write MAP and ROW columns via write_arrow_batch and
    verify through both the record and Arrow scan paths."""
    table_path = fluss.TablePath("fluss", "py_test_arrow_batch_complex")
    await admin.drop_table(table_path, ignore_if_not_exists=True)

    row_type = pa.struct([("seq", pa.int32()), ("label", pa.string())])
    map_type = pa.map_(pa.string(), pa.int32())
    pa_schema = pa.schema(
        [
            pa.field("id", pa.int32()),
            pa.field("attrs", map_type),
            pa.field("nested", row_type),
        ]
    )
    schema = fluss.Schema(pa_schema)
    await admin.create_table(
        table_path, fluss.TableDescriptor(schema), ignore_if_exists=False
    )

    table = await connection.get_table(table_path)
    append_writer = table.new_append().create_writer()
    batch = pa.RecordBatch.from_arrays(
        [
            pa.array([1, 2], type=pa.int32()),
            pa.array([[("a", 1), ("b", 2)], []], type=map_type),
            pa.array(
                [{"seq": 10, "label": "open"}, {"seq": 20, "label": None}],
                type=row_type,
            ),
        ],
        schema=pa_schema,
    )
    append_writer.write_arrow_batch(batch)
    await append_writer.flush()

    # Record scan path.
    scanner = await table.new_scan().create_log_scanner()
    scanner.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
    records = await _poll_records(scanner, expected_count=2)
    assert len(records) == 2
    rows = sorted([r.row for r in records], key=lambda r: r["id"])
    assert dict(rows[0]["attrs"]) == {"a": 1, "b": 2}
    assert rows[0]["nested"] == {"seq": 10, "label": "open"}
    assert rows[1]["attrs"] == []
    assert rows[1]["nested"] == {"seq": 20, "label": None}

    # Arrow scan path.
    scanner2 = await table.new_scan().create_record_batch_log_scanner()
    scanner2.subscribe_buckets({0: fluss.EARLIEST_OFFSET})
    result_table = await scanner2.to_arrow()
    assert result_table.column("id").to_pylist() == [1, 2]
    assert result_table.column("attrs").to_pylist() == [[("a", 1), ("b", 2)], []]
    assert result_table.column("nested").to_pylist() == [
        {"seq": 10, "label": "open"},
        {"seq": 20, "label": None},
    ]

    await admin.drop_table(table_path, ignore_if_not_exists=False)
