# 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 os
from datetime import date

import numpy as np
import pandas as pd
import pytest

from tsfile import ColumnSchema, TableSchema, TSDataType, ColumnCategory
from tsfile import Tablet
from tsfile import TsFileTableWriter, TsFileReader


def test_batch_read_arrow_basic():
    file_path = "test_batch_arrow_basic.tsfile"
    table = TableSchema(
        "test_table",
        [
            ColumnSchema("device", TSDataType.STRING, ColumnCategory.TAG),
            ColumnSchema("value1", TSDataType.INT64, ColumnCategory.FIELD),
            ColumnSchema("value2", TSDataType.DOUBLE, ColumnCategory.FIELD),
        ],
    )
    
    try:
        if os.path.exists(file_path):
            os.remove(file_path)
        print("t1")

        with TsFileTableWriter(file_path, table) as writer:
            tablet = Tablet(
                ["device", "value1", "value2"],
                [TSDataType.STRING, TSDataType.INT64, TSDataType.DOUBLE],
                1000,
            )
            for i in range(1000):
                tablet.add_timestamp(i, i)
                tablet.add_value_by_name("device", i, f"device_{i}")
                tablet.add_value_by_name("value1", i, i * 10)
                tablet.add_value_by_name("value2", i, i * 1.5)
            writer.write_table(tablet)
        try:
            import pyarrow as pa
        except ImportError:
            pytest.skip("pyarrow is not installed")
        
        reader = TsFileReader(file_path)
        result_set = reader.query_table_batch(
            table_name="test_table",
            column_names=["device", "value1", "value2"],
            start_time=0,
            end_time=1000,
            batch_size=256,
        )
        
        total_rows = 0
        batch_count = 0
        while True:
            table = result_set.read_arrow_batch()
            if table is None:
                break
            
            batch_count += 1
            assert isinstance(table, pa.Table)
            assert len(table) > 0
            total_rows += len(table)

            column_names = table.column_names
            assert "time" in column_names
            assert "device" in column_names
            assert "value1" in column_names
            assert "value2" in column_names
        
        assert total_rows == 1000
        assert batch_count > 0
        
        result_set.close()
        reader.close()
        
    finally:
        if os.path.exists(file_path):
            os.remove(file_path)


def test_batch_read_arrow_compare_with_dataframe():
    file_path = "test_batch_arrow_compare.tsfile"
    table = TableSchema(
        "test_table",
        [
            ColumnSchema("device", TSDataType.STRING, ColumnCategory.TAG),
            ColumnSchema("value1", TSDataType.INT32, ColumnCategory.FIELD),
            ColumnSchema("value2", TSDataType.FLOAT, ColumnCategory.FIELD),
            ColumnSchema("value3", TSDataType.BOOLEAN, ColumnCategory.FIELD),
        ],
    )
    
    try:
        if os.path.exists(file_path):
            os.remove(file_path)

        with TsFileTableWriter(file_path, table) as writer:
            tablet = Tablet(
                ["device", "value1", "value2", "value3"],
                [TSDataType.STRING, TSDataType.INT32, TSDataType.FLOAT, TSDataType.BOOLEAN],
                500,
            )
            for i in range(500):
                tablet.add_timestamp(i, i)
                tablet.add_value_by_name("device", i, f"device_{i}")
                tablet.add_value_by_name("value1", i, i * 2)
                tablet.add_value_by_name("value2", i, i * 1.1)
                tablet.add_value_by_name("value3", i, i % 2 == 0)
            writer.write_table(tablet)
        
        try:
            import pyarrow as pa
        except ImportError:
            pytest.skip("pyarrow is not installed")

        reader1 = TsFileReader(file_path)
        result_set1 = reader1.query_table_batch(
            table_name="test_table",
            column_names=["device", "value1", "value2", "value3"],
            start_time=0,
            end_time=500,
            batch_size=100,
        )
        
        arrow_tables = []
        while True:
            table = result_set1.read_arrow_batch()
            if table is None:
                break
            arrow_tables.append(table)

        if arrow_tables:
            combined_arrow_table = pa.concat_tables(arrow_tables)
            df_arrow = combined_arrow_table.to_pandas()
        else:
            df_arrow = pd.DataFrame()
        
        result_set1.close()
        reader1.close()
        reader2 = TsFileReader(file_path)
        result_set2 = reader2.query_table(
            table_name="test_table",
            column_names=["device", "value1", "value2", "value3"],
            start_time=0,
            end_time=500,
        )
        
        df_traditional = result_set2.read_data_frame(max_row_num=1000)
        result_set2.close()
        reader2.close()

        assert len(df_arrow) == len(df_traditional)
        assert len(df_arrow) == 500

        for col in ["time", "device", "value1", "value2", "value3"]:
            assert col in df_arrow.columns
            assert col in df_traditional.columns

        df_arrow_sorted = df_arrow.sort_values("time").reset_index(drop=True)
        df_traditional_sorted = df_traditional.sort_values("time").reset_index(drop=True)
        
        for i in range(len(df_arrow_sorted)):
            assert df_arrow_sorted.iloc[i]["time"] == df_traditional_sorted.iloc[i]["time"]
            assert df_arrow_sorted.iloc[i]["device"] == df_traditional_sorted.iloc[i]["device"]
            assert df_arrow_sorted.iloc[i]["value1"] == df_traditional_sorted.iloc[i]["value1"]
            assert abs(df_arrow_sorted.iloc[i]["value2"] - df_traditional_sorted.iloc[i]["value2"]) < 1e-5
            assert df_arrow_sorted.iloc[i]["value3"] == df_traditional_sorted.iloc[i]["value3"]
        
    finally:
        if os.path.exists(file_path):
            os.remove(file_path)


def test_batch_read_arrow_empty_result():
    file_path = "test_batch_arrow_empty.tsfile"
    table = TableSchema(
        "test_table",
        [
            ColumnSchema("device", TSDataType.STRING, ColumnCategory.TAG),
            ColumnSchema("value", TSDataType.INT64, ColumnCategory.FIELD),
        ],
    )
    
    try:
        if os.path.exists(file_path):
            os.remove(file_path)

        with TsFileTableWriter(file_path, table) as writer:
            tablet = Tablet(
                ["device", "value"],
                [TSDataType.STRING, TSDataType.INT64],
                10,
            )
            for i in range(10):
                tablet.add_timestamp(i, i)
                tablet.add_value_by_name("device", i, f"device_{i}")
                tablet.add_value_by_name("value", i, i)
            writer.write_table(tablet)
        
        try:
            import pyarrow as pa
        except ImportError:
            pytest.skip("pyarrow is not installed")

        reader = TsFileReader(file_path)
        result_set = reader.query_table_batch(
            table_name="test_table",
            column_names=["device", "value"],
            start_time=1000,
            end_time=2000,
            batch_size=100,
        )

        table = result_set.read_arrow_batch()
        assert table is None
        
        result_set.close()
        reader.close()
        
    finally:
        if os.path.exists(file_path):
            os.remove(file_path)


def test_batch_read_arrow_time_range():

    file_path = "test_batch_arrow_time_range.tsfile"
    table = TableSchema(
        "test_table",
        [
            ColumnSchema("device", TSDataType.STRING, ColumnCategory.TAG),
            ColumnSchema("value", TSDataType.INT64, ColumnCategory.FIELD),
        ],
    )
    
    try:
        if os.path.exists(file_path):
            os.remove(file_path)

        with TsFileTableWriter(file_path, table) as writer:
            tablet = Tablet(
                ["device", "value"],
                [TSDataType.STRING, TSDataType.INT64],
                1000,
            )
            for i in range(1000):
                tablet.add_timestamp(i, i)
                tablet.add_value_by_name("device", i, f"device_{i}")
                tablet.add_value_by_name("value", i, i)
            writer.write_table(tablet)
        
        try:
            import pyarrow as pa
        except ImportError:
            pytest.skip("pyarrow is not installed")

        reader = TsFileReader(file_path)
        result_set = reader.query_table_batch(
            table_name="test_table",
            column_names=["device", "value"],
            start_time=100,
            end_time=199,
            batch_size=50,
        )
        
        total_rows = 0
        while True:
            table = result_set.read_arrow_batch()
            if table is None:
                break
            total_rows += len(table)
            df = table.to_pandas()
            assert df["time"].min() >= 100
            assert df["time"].max() <= 199
        
        assert total_rows == 100
        
        result_set.close()
        reader.close()
        
    finally:
        if os.path.exists(file_path):
            os.remove(file_path)


def test_batch_read_arrow_all_datatypes():
    file_path = "test_batch_arrow_all_datatypes.tsfile"
    table = TableSchema(
        "test_table",
        [
            ColumnSchema("device", TSDataType.STRING, ColumnCategory.TAG),
            ColumnSchema("bool_val", TSDataType.BOOLEAN, ColumnCategory.FIELD),
            ColumnSchema("int32_val", TSDataType.INT32, ColumnCategory.FIELD),
            ColumnSchema("int64_val", TSDataType.INT64, ColumnCategory.FIELD),
            ColumnSchema("float_val", TSDataType.FLOAT, ColumnCategory.FIELD),
            ColumnSchema("double_val", TSDataType.DOUBLE, ColumnCategory.FIELD),
            ColumnSchema("string_val", TSDataType.STRING, ColumnCategory.FIELD),
            ColumnSchema("date_val", TSDataType.DATE, ColumnCategory.FIELD),
        ],
    )
    
    try:
        if os.path.exists(file_path):
            os.remove(file_path)

        with TsFileTableWriter(file_path, table) as writer:
            tablet = Tablet(
                ["device", "bool_val", "int32_val", "int64_val", "float_val", "double_val", "string_val", "date_val"],
                [
                    TSDataType.STRING,
                    TSDataType.BOOLEAN,
                    TSDataType.INT32,
                    TSDataType.INT64,
                    TSDataType.FLOAT,
                    TSDataType.DOUBLE,
                    TSDataType.STRING,
                    TSDataType.DATE,
                ],
                200,
            )
            for i in range(200):
                tablet.add_timestamp(i, i)
                tablet.add_value_by_name("device", i, f"device_{i}")
                tablet.add_value_by_name("bool_val", i, i % 2 == 0)
                tablet.add_value_by_name("int32_val", i, i * 2)
                tablet.add_value_by_name("int64_val", i, i * 3)
                tablet.add_value_by_name("float_val", i, i * 1.1)
                tablet.add_value_by_name("double_val", i, i * 2.2)
                tablet.add_value_by_name("string_val", i, f"string_{i}")
                tablet.add_value_by_name("date_val", i, date(2025, 1, (i % 28) + 1))
            writer.write_table(tablet)
        
        try:
            import pyarrow as pa
        except ImportError:
            pytest.skip("pyarrow is not installed")

        reader = TsFileReader(file_path)
        result_set = reader.query_table_batch(
            table_name="test_table",
            column_names=["device", "bool_val", "int32_val", "int64_val", "float_val", "double_val", "string_val", "date_val"],
            start_time=0,
            end_time=200,
            batch_size=50,
        )
        
        total_rows = 0
        while True:
            table = result_set.read_arrow_batch()
            if table is None:
                break
            
            total_rows += len(table)
            df = table.to_pandas()

            assert "time" in df.columns
            assert "device" in df.columns
            assert "bool_val" in df.columns
            assert "int32_val" in df.columns
            assert "int64_val" in df.columns
            assert "float_val" in df.columns
            assert "double_val" in df.columns
            assert "string_val" in df.columns
            assert "date_val" in df.columns
        
        assert total_rows == 200
        
        result_set.close()
        reader.close()
        
    finally:
        if os.path.exists(file_path):
            os.remove(file_path)


def test_batch_read_arrow_no_pyarrow():
    file_path = "test_batch_arrow_no_pyarrow.tsfile"
    table = TableSchema(
        "test_table",
        [
            ColumnSchema("device", TSDataType.STRING, ColumnCategory.TAG),
            ColumnSchema("value", TSDataType.INT64, ColumnCategory.FIELD),
        ],
    )
    
    try:
        if os.path.exists(file_path):
            os.remove(file_path)

        with TsFileTableWriter(file_path, table) as writer:
            tablet = Tablet(
                ["device", "value"],
                [TSDataType.STRING, TSDataType.INT64],
                10,
            )
            for i in range(10):
                tablet.add_timestamp(i, i)
                tablet.add_value_by_name("device", i, f"device_{i}")
                tablet.add_value_by_name("value", i, i)
            writer.write_table(tablet)
        
        reader = TsFileReader(file_path)
        result_set = reader.query_table_batch(
            table_name="test_table",
            column_names=["device", "value"],
            start_time=0,
            end_time=10,
            batch_size=5,
        )
        result_set.close()
        reader.close()
        
    finally:
        if os.path.exists(file_path):
            os.remove(file_path)


if __name__ == "__main__":
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    pytest.main([
        "test_batch_arrow.py",
        "-s", "-v"
    ])
