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

import datetime
from decimal import Decimal
from unittest.mock import patch

import pyarrow as pa
import pytest

from pypaimon import CatalogFactory, Schema
from pypaimon.table.row.generic_row import GenericRow


pytestmark = pytest.mark.python_write


@pytest.fixture
def make_table(tmp_path):
    catalog = CatalogFactory.create({'warehouse': str(tmp_path)})
    catalog.create_database('default', True)

    def create(options=None, sequence_type=None, partitioned=False):
        arrow_schema = pa.schema([
            pa.field('id', pa.int64(), nullable=False),
            ('seq', sequence_type if sequence_type is not None else pa.int64()),
            ('seq2', pa.int64()), ('val', pa.string()), ('pt', pa.string()),
        ])
        opts = {'bucket': '1', 'sequence.field': 'seq'}
        opts.update(options or {})
        catalog.create_table('default.t', Schema.from_pyarrow_schema(
            arrow_schema, primary_keys=['pt', 'id'] if partitioned else ['id'],
            partition_keys=['pt'] if partitioned else [], options=opts), False)
        return catalog.get_table('default.t'), arrow_schema

    return create


def write_rows(table, schema, rows, grouping='batch', streaming=False):
    builder = (table.new_stream_write_builder() if streaming
               else table.new_batch_write_builder())
    commit = builder.new_commit()
    groups = [[row] for row in rows] if grouping == 'commits' else [rows]
    try:
        for identifier, group in enumerate(groups, 1):
            writer = builder.new_write()
            try:
                batch = pa.Table.from_pylist(group, schema=schema)
                if grouping == 'chunks':
                    for chunk in batch.to_batches(max_chunksize=1):
                        writer.write_arrow_batch(chunk)
                elif grouping == 'rows':
                    for row in group:
                        writer.write_row(GenericRow(
                            [row.get(field.name) for field in table.fields], table.fields))
                else:
                    writer.write_arrow(batch)
                if streaming:
                    commit.commit(writer.prepare_commit(identifier), identifier)
                else:
                    commit.commit(writer.prepare_commit())
                    commit.close()
                    commit = builder.new_commit()
            finally:
                writer.close()
    finally:
        commit.close()


def read_rows(table, projection=None):
    builder = table.new_read_builder()
    if projection is not None:
        builder.with_projection(projection)
    return builder.new_read().to_arrow(builder.new_scan().plan().splits()).sort_by('id').to_pylist()


@pytest.mark.parametrize('engine', ['deduplicate', 'partial-update'])
@pytest.mark.parametrize('grouping', ['batch', 'chunks', 'rows', 'commits'])
@pytest.mark.parametrize('order', ['ascending', 'descending'])
@pytest.mark.parametrize('streaming', [False, True])
def test_sequence_order_is_independent_of_write_grouping(
        make_table, engine, grouping, order, streaming):
    table, schema = make_table({'merge-engine': engine, 'sequence.field.sort-order': order})
    rows = [
        {'id': 1, 'seq': 100, 'val': 'high'},
        {'id': 2, 'seq': 100, 'val': 'tie-first'},
        {'id': 3, 'seq': 100, 'val': 'non-null'},
        {'id': 4, 'seq': None, 'val': 'null-first'},
        {'id': 1, 'seq': 50, 'val': 'low'},
        {'id': 2, 'seq': 100, 'val': 'tie-last'},
        {'id': 3, 'seq': None, 'val': 'null'},
        {'id': 4, 'seq': None, 'val': 'null-last'},
    ]
    write_rows(table, schema, rows, grouping, streaming)
    assert read_rows(table, ['id', 'val']) == [
        {'id': 1, 'val': 'high' if order == 'ascending' else 'low'},
        {'id': 2, 'val': 'tie-last'},
        {'id': 3, 'val': 'non-null'},
        {'id': 4, 'val': 'null-last'},
    ]


def test_partial_update_fills_nulls_in_sequence_order(make_table):
    table, schema = make_table({'merge-engine': 'partial-update'})
    write_rows(table, schema, [
        {'id': 1, 'seq': 100, 'seq2': 2, 'val': None},
        {'id': 1, 'seq': 50, 'seq2': 1, 'val': 'filled'},
    ], 'chunks')
    assert read_rows(table, ['id', 'seq', 'seq2', 'val']) == [
        {'id': 1, 'seq': 100, 'seq2': 2, 'val': 'filled'},
    ]


def test_sequence_order_across_buffer_flushes(make_table):
    table, schema = make_table({'target-file-size': '1 b'})
    write_rows(table, schema, [
        {'id': 1, 'seq': 100, 'val': 'high'},
        {'id': 1, 'seq': 50, 'val': 'low'},
    ], 'chunks')
    assert read_rows(table, ['id', 'val']) == [{'id': 1, 'val': 'high'}]


@pytest.mark.parametrize('order,expected', [('ascending', 'high'), ('descending', 'low')])
def test_compound_sequence_in_partitioned_table(make_table, order, expected):
    table, schema = make_table({
        'sequence.field': 'seq,seq2', 'sequence.field.sort-order': order,
    }, partitioned=True)
    rows = []
    for pt in ['a', 'b']:
        rows.extend([
            {'id': 1, 'pt': pt, 'seq': 10, 'seq2': 2, 'val': 'high'},
            {'id': 1, 'pt': pt, 'seq': 9, 'seq2': 99, 'val': 'low'},
            {'id': 1, 'pt': pt, 'seq': 10, 'seq2': 1, 'val': 'middle'},
            {'id': 1, 'pt': pt, 'seq': 10, 'seq2': None, 'val': 'null'},
        ])
    write_rows(table, schema, rows, 'chunks')
    assert sorted(read_rows(table, ['id', 'pt', 'val']), key=lambda row: row['pt']) == [
        {'id': 1, 'pt': pt, 'val': expected} for pt in ['a', 'b']
    ]


@pytest.mark.parametrize('type_,high,low', [
    (pa.decimal128(10, 2), Decimal('100.50'), Decimal('50.25')),
    (pa.timestamp('us'), datetime.datetime(2020, 1, 2), datetime.datetime(2020, 1, 1)),
    (pa.date32(), datetime.date(2020, 1, 2), datetime.date(2020, 1, 1)),
    (pa.time32('ms'), datetime.time(12, 0), datetime.time(1, 0)),
    (pa.float64(), 2.5, -1.0),
    (pa.binary(), b'z', b'a'),
])
def test_typed_sequence_fields(make_table, type_, high, low):
    table, schema = make_table(sequence_type=type_)
    write_rows(table, schema, [
        {'id': 1, 'seq': high, 'val': 'high'},
        {'id': 1, 'seq': low, 'val': 'low'},
    ])
    assert read_rows(table)[0]['seq'] == high
    assert read_rows(table, ['id', 'val']) == [{'id': 1, 'val': 'high'}]


@pytest.mark.parametrize('type_', [pa.float32(), pa.float64()])
@pytest.mark.parametrize('order', ['ascending', 'descending'])
@pytest.mark.parametrize('grouping', ['batch', 'chunks', 'commits'])
@pytest.mark.parametrize('streaming', [False, True])
def test_floating_sequence_order(make_table, type_, order, grouping, streaming):
    table, schema = make_table({
        'sequence.field.sort-order': order,
        'write.native.enabled': 'true', 'read.native.enabled': 'true',
    }, sequence_type=type_)
    # Pairs are in Java Float/Double.compare order, with null always first.
    pairs = [
        (float('-inf'), 1.0), (1.0, float('inf')),
        (-0.0, 0.0), (None, 0.0),
    ]
    rows, expected = [], []
    for low, high in pairs:
        for reverse in (False, True):
            key = len(expected)
            pair = [{'id': key, 'seq': low, 'val': 'low'},
                    {'id': key, 'seq': high, 'val': 'high'}]
            rows.extend(reversed(pair) if reverse else pair)
            expected.append({'id': key, 'val': 'high' if low is None or order == 'ascending'
                             else 'low'})
    for values in ((None, None), (-0.0, -0.0)):
        key = len(expected)
        rows.extend({'id': key, 'seq': value, 'val': label}
                    for value, label in zip(values, ('first', 'last')))
        expected.append({'id': key, 'val': 'last'})
    write_rows(table, schema, rows, grouping, streaming)
    assert read_rows(table, ['id', 'val']) == expected


@pytest.mark.parametrize('streaming', [False, True])
@pytest.mark.parametrize('direct', [False, True])
@pytest.mark.parametrize('sequence,type_,error', [
    ('missing', pa.int64(), ValueError),
    ('seq,seq', pa.int64(), ValueError),
    ('seq,,seq2', pa.int64(), ValueError),
    ('seq', pa.list_(pa.int64()), NotImplementedError),
])
def test_dynamic_bucket_sequence_rejected_before_index_creation(
        make_table, streaming, direct, sequence, type_, error):
    from pathlib import Path
    from pypaimon.write.table_write import BatchTableWrite, StreamTableWrite

    table, _ = make_table({'bucket': '-1', 'sequence.field': sequence}, sequence_type=type_)
    builder = (table.new_stream_write_builder() if streaming
               else table.new_batch_write_builder())
    writer_class = StreamTableWrite if streaming else BatchTableWrite
    with patch('pypaimon.execution.python.write.row_key_extractor.create_row_key_extractor') as extractor:
        with pytest.raises(error):
            if direct:
                writer_class(table, 'test')
            else:
                builder.new_write()
        extractor.assert_not_called()
    assert table.snapshot_manager().get_latest_snapshot() is None
    assert list(Path(table.table_path).glob('index/*')) == []
    assert list(Path(table.table_path).rglob('*.parquet')) == []
