# 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 ctypes
import os
import platform
from ctypes import (
    CFUNCTYPE,
    POINTER,
    Structure,
    c_char_p,
    c_float,
    c_int,
    c_int64,
    c_size_t,
    c_uint8,
    c_uint32,
    c_uint64,
    c_void_p,
)


def _lib_name():
    system = platform.system()
    if system == "Darwin":
        return "libpaimon_vindex_ffi.dylib"
    if system == "Windows":
        return "paimon_vindex_ffi.dll"
    return "libpaimon_vindex_ffi.so"


def _load_library():
    lib_name = _lib_name()
    search_paths = []

    env_path = os.environ.get("PAIMON_VINDEX_LIB_PATH")
    if env_path:
        if os.path.isfile(env_path):
            return ctypes.CDLL(env_path)
        search_paths.append(env_path)

    pkg_dir = os.path.dirname(os.path.abspath(__file__))
    search_paths.append(pkg_dir)
    search_paths.append(os.path.join(pkg_dir, "..", ".."))

    for rel in [
        os.path.join("..", "..", "target", "release"),
        os.path.join("..", "..", "target", "debug"),
        os.path.join("..", "..", "..", "target", "release"),
        os.path.join("..", "..", "..", "target", "debug"),
    ]:
        search_paths.append(os.path.join(pkg_dir, rel))

    for directory in search_paths:
        candidate = os.path.abspath(os.path.join(directory, lib_name))
        if os.path.isfile(candidate):
            return ctypes.CDLL(candidate)

    try:
        return ctypes.CDLL(lib_name)
    except OSError as exc:
        raise OSError(
            f"Cannot find {lib_name}. Build the native library first with "
            "'cargo build --release -p paimon-vindex-ffi', or set "
            "PAIMON_VINDEX_LIB_PATH to the directory containing it."
        ) from exc


lib = _load_library()

WRITE_FN = CFUNCTYPE(c_int, c_void_p, POINTER(c_uint8), c_size_t)
FLUSH_FN = CFUNCTYPE(c_int, c_void_p)
GET_POS_FN = CFUNCTYPE(c_int64, c_void_p)
READ_AT_FN = CFUNCTYPE(c_int, c_void_p, c_uint64, POINTER(c_uint8), c_size_t)


class PaimonVindexOutputFile(Structure):
    _fields_ = [
        ("ctx", c_void_p),
        ("write_fn", WRITE_FN),
        ("flush_fn", FLUSH_FN),
        ("get_pos_fn", GET_POS_FN),
    ]


class PaimonVindexInputFile(Structure):
    _fields_ = [
        ("ctx", c_void_p),
        ("read_at_fn", READ_AT_FN),
    ]


class PaimonVindexMetadata(Structure):
    _fields_ = [
        ("index_type", c_uint32),
        ("dimension", c_size_t),
        ("nlist", c_size_t),
        ("metric", c_uint32),
        ("total_vectors", c_int64),
        ("pq_m", c_size_t),
        ("hnsw_m", c_size_t),
        ("hnsw_ef_construction", c_size_t),
        ("hnsw_max_level", c_size_t),
    ]


class PaimonVindexSearchParams(Structure):
    _fields_ = [
        ("top_k", c_size_t),
        ("nprobe", c_size_t),
        ("ef_search", c_size_t),
        ("query_bits", c_size_t),
    ]


lib.paimon_vindex_last_error.argtypes = []
lib.paimon_vindex_last_error.restype = c_char_p

lib.paimon_vindex_trainer_open.argtypes = [
    POINTER(c_char_p),
    POINTER(c_char_p),
    c_size_t,
]
lib.paimon_vindex_trainer_open.restype = c_void_p

lib.paimon_vindex_trainer_free.argtypes = [c_void_p]
lib.paimon_vindex_trainer_free.restype = None

lib.paimon_vindex_trainer_dimension.argtypes = [c_void_p, POINTER(c_size_t)]
lib.paimon_vindex_trainer_dimension.restype = c_int

lib.paimon_vindex_trainer_add_training_vectors.argtypes = [
    c_void_p,
    POINTER(c_float),
    c_size_t,
]
lib.paimon_vindex_trainer_add_training_vectors.restype = c_int

lib.paimon_vindex_trainer_finish.argtypes = [c_void_p]
lib.paimon_vindex_trainer_finish.restype = c_void_p

lib.paimon_vindex_training_free.argtypes = [c_void_p]
lib.paimon_vindex_training_free.restype = None

lib.paimon_vindex_writer_open.argtypes = [c_void_p]
lib.paimon_vindex_writer_open.restype = c_void_p

lib.paimon_vindex_writer_free.argtypes = [c_void_p]
lib.paimon_vindex_writer_free.restype = None

lib.paimon_vindex_writer_dimension.argtypes = [c_void_p, POINTER(c_size_t)]
lib.paimon_vindex_writer_dimension.restype = c_int

lib.paimon_vindex_writer_add_vectors.argtypes = [
    c_void_p,
    POINTER(c_int64),
    POINTER(c_float),
    c_size_t,
]
lib.paimon_vindex_writer_add_vectors.restype = c_int

lib.paimon_vindex_writer_write_index.argtypes = [
    c_void_p,
    PaimonVindexOutputFile,
]
lib.paimon_vindex_writer_write_index.restype = c_int

lib.paimon_vindex_reader_open.argtypes = [PaimonVindexInputFile]
lib.paimon_vindex_reader_open.restype = c_void_p

lib.paimon_vindex_reader_free.argtypes = [c_void_p]
lib.paimon_vindex_reader_free.restype = None

lib.paimon_vindex_reader_metadata.argtypes = [
    c_void_p,
    POINTER(PaimonVindexMetadata),
]
lib.paimon_vindex_reader_metadata.restype = c_int

lib.paimon_vindex_reader_optimize_for_search.argtypes = [c_void_p]
lib.paimon_vindex_reader_optimize_for_search.restype = c_int

lib.paimon_vindex_reader_search.argtypes = [
    c_void_p,
    POINTER(c_float),
    PaimonVindexSearchParams,
    POINTER(c_int64),
    POINTER(c_float),
    c_size_t,
]
lib.paimon_vindex_reader_search.restype = c_int

lib.paimon_vindex_reader_search_with_roaring_filter.argtypes = [
    c_void_p,
    POINTER(c_float),
    PaimonVindexSearchParams,
    POINTER(c_uint8),
    c_size_t,
    POINTER(c_int64),
    POINTER(c_float),
    c_size_t,
]
lib.paimon_vindex_reader_search_with_roaring_filter.restype = c_int

lib.paimon_vindex_reader_search_batch.argtypes = [
    c_void_p,
    POINTER(c_float),
    c_size_t,
    PaimonVindexSearchParams,
    POINTER(c_int64),
    POINTER(c_float),
    c_size_t,
]
lib.paimon_vindex_reader_search_batch.restype = c_int

lib.paimon_vindex_reader_search_batch_with_roaring_filter.argtypes = [
    c_void_p,
    POINTER(c_float),
    c_size_t,
    PaimonVindexSearchParams,
    POINTER(c_uint8),
    c_size_t,
    POINTER(c_int64),
    POINTER(c_float),
    c_size_t,
]
lib.paimon_vindex_reader_search_batch_with_roaring_filter.restype = c_int
