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

from dataclasses import dataclass
from typing import Mapping, Optional

import ctypes
import numpy as np

from . import _ffi
from ._ffi import lib

INDEX_TYPES = {
    0: "ivf_flat",
    1: "ivf_pq",
    2: "ivf_hnsw_flat",
    3: "ivf_hnsw_sq",
    4: "ivf_rq",
}

METRICS = {
    0: "l2",
    1: "inner_product",
    2: "cosine",
}


@dataclass(frozen=True)
class VectorIndexMetadata:
    index_type: str
    dimension: int
    nlist: int
    metric: str
    total_vectors: int
    pq_m: Optional[int] = None
    hnsw_m: Optional[int] = None
    hnsw_ef_construction: Optional[int] = None
    hnsw_max_level: Optional[int] = None


@dataclass(frozen=True)
class SearchParams:
    top_k: int
    nprobe: int
    ef_search: int = 0
    query_bits: int = 0

    def to_ffi(self):
        return _ffi.PaimonVindexSearchParams(
            self.top_k,
            self.nprobe,
            self.ef_search,
            self.query_bits,
        )


def _check_error(message="operation failed"):
    err = lib.paimon_vindex_last_error()
    if err:
        raise RuntimeError(err.decode("utf-8", errors="replace"))
    raise RuntimeError(message)


def _metadata_from_ffi(raw):
    return VectorIndexMetadata(
        index_type=INDEX_TYPES.get(raw.index_type, f"unknown_{raw.index_type}"),
        dimension=raw.dimension,
        nlist=raw.nlist,
        metric=METRICS.get(raw.metric, f"unknown_{raw.metric}"),
        total_vectors=raw.total_vectors,
        pq_m=raw.pq_m or None,
        hnsw_m=raw.hnsw_m or None,
        hnsw_ef_construction=raw.hnsw_ef_construction or None,
        hnsw_max_level=raw.hnsw_max_level or None,
    )


def _float32_matrix(value, name):
    array = np.asarray(value, dtype=np.float32)
    if array.ndim != 2:
        raise ValueError(f"{name} must be a two-dimensional float32 array")
    return np.ascontiguousarray(array)


def _float32_vector(value, name):
    array = np.asarray(value, dtype=np.float32)
    if array.ndim != 1:
        raise ValueError(f"{name} must be a one-dimensional float32 array")
    return np.ascontiguousarray(array)


def _int64_vector(value, name):
    array = np.asarray(value, dtype=np.int64)
    if array.ndim != 1:
        raise ValueError(f"{name} must be a one-dimensional int64 array")
    return np.ascontiguousarray(array)


def _bytes_buffer(value, name):
    if isinstance(value, memoryview):
        value = value.tobytes()
    if not isinstance(value, (bytes, bytearray)):
        raise ValueError(f"{name} must be bytes")
    data = bytes(value)
    if not data:
        return None, 0, data
    buf = (ctypes.c_uint8 * len(data)).from_buffer_copy(data)
    return buf, len(data), data


def _option_arrays(options: Mapping[str, str]):
    option_items = list(options.items())
    key_bytes = []
    value_bytes = []
    for key, value in option_items:
        if not isinstance(key, str) or not isinstance(value, str):
            raise ValueError("options must be a mapping of str to str")
        key_bytes.append(key.encode("utf-8"))
        value_bytes.append(value.encode("utf-8"))
    keys = (ctypes.c_char_p * len(key_bytes))(*key_bytes)
    values = (ctypes.c_char_p * len(value_bytes))(*value_bytes)
    return option_items, key_bytes, value_bytes, keys, values


class VectorIndexTraining:
    def __init__(self, handle):
        self._closed = False
        self._handle = handle

    def _require_open(self):
        if self._closed or not self._handle:
            raise RuntimeError("VectorIndexTraining is closed")

    def _take_handle(self):
        self._require_open()
        handle = self._handle
        self._handle = None
        self._closed = True
        return handle

    def close(self):
        if self._handle:
            lib.paimon_vindex_training_free(self._handle)
            self._handle = None
        self._closed = True

    def __enter__(self):
        self._require_open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False

    def __del__(self):
        try:
            self.close()
        except Exception:
            pass


class VectorIndexTrainer:
    def __init__(self, options: Mapping[str, str]):
        self._closed = False
        (
            option_items,
            self._key_bytes,
            self._value_bytes,
            self._keys,
            self._values,
        ) = _option_arrays(options)
        self._handle = lib.paimon_vindex_trainer_open(
            self._keys,
            self._values,
            len(option_items),
        )
        if not self._handle:
            _check_error("failed to open trainer")
        self._dimension = self._read_dimension()

    @classmethod
    def create(cls, options: Mapping[str, str]):
        return cls(options)

    @classmethod
    def train(cls, options: Mapping[str, str], data):
        with cls(options) as trainer:
            return trainer.add_training_vectors(data).finish_training()

    def _require_open(self):
        if self._closed or not self._handle:
            raise RuntimeError("VectorIndexTrainer is closed")

    def _read_dimension(self):
        out = ctypes.c_size_t(0)
        rc = lib.paimon_vindex_trainer_dimension(self._handle, ctypes.byref(out))
        if rc != 0:
            _check_error("trainer dimension failed")
        return out.value

    @property
    def dimension(self):
        self._require_open()
        return self._dimension

    def add_training_vectors(self, data):
        self._require_open()
        data = _float32_matrix(data, "data")
        if data.shape[1] != self._dimension:
            raise RuntimeError(
                f"training data length {data.size} does not match vector count "
                f"* dimension {data.shape[0] * self._dimension}"
            )
        rc = lib.paimon_vindex_trainer_add_training_vectors(
            self._handle,
            data.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
            data.shape[0],
        )
        if rc != 0:
            _check_error("add training vectors failed")
        return self

    def finish_training(self):
        self._require_open()
        handle = self._handle
        training = lib.paimon_vindex_trainer_finish(handle)
        lib.paimon_vindex_trainer_free(handle)
        self._handle = None
        self._closed = True
        if not training:
            _check_error("finish training failed")
        return VectorIndexTraining(training)

    def close(self):
        if self._handle:
            lib.paimon_vindex_trainer_free(self._handle)
            self._handle = None
        self._closed = True

    def __enter__(self):
        self._require_open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False

    def __del__(self):
        try:
            self.close()
        except Exception:
            pass


class VectorIndexWriter:
    def __init__(self, training: VectorIndexTraining):
        if not isinstance(training, VectorIndexTraining):
            raise TypeError("training must be a VectorIndexTraining")
        self._closed = False
        training_handle = training._take_handle()
        self._handle = lib.paimon_vindex_writer_open(training_handle)
        lib.paimon_vindex_training_free(training_handle)
        if not self._handle:
            _check_error("failed to open writer")
        self._dimension = self._read_dimension()

    def _require_open(self):
        if self._closed or not self._handle:
            raise RuntimeError("VectorIndexWriter is closed")

    def _read_dimension(self):
        out = ctypes.c_size_t(0)
        rc = lib.paimon_vindex_writer_dimension(self._handle, ctypes.byref(out))
        if rc != 0:
            _check_error("writer dimension failed")
        return out.value

    @property
    def dimension(self):
        self._require_open()
        return self._dimension

    def add_vectors(self, ids, data):
        self._require_open()
        data = _float32_matrix(data, "data")
        ids = _int64_vector(ids, "ids")
        if data.shape[1] != self._dimension:
            raise RuntimeError(
                f"vector data length {data.size} does not match vector count "
                f"* dimension {data.shape[0] * self._dimension}"
            )
        if ids.shape[0] != data.shape[0]:
            raise RuntimeError(
                f"ids length {ids.shape[0]} does not match vector count {data.shape[0]}"
            )
        rc = lib.paimon_vindex_writer_add_vectors(
            self._handle,
            ids.ctypes.data_as(ctypes.POINTER(ctypes.c_int64)),
            data.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
            data.shape[0],
        )
        if rc != 0:
            _check_error("add_vectors failed")

    def write(self, file):
        self._require_open()
        pos = 0

        @_ffi.WRITE_FN
        def write_callback(ctx, data, length):
            nonlocal pos
            try:
                payload = ctypes.string_at(data, length)
                written = file.write(payload)
                if written is not None and written != length:
                    return -1
                pos += length
                return 0
            except Exception:
                return -1

        @_ffi.FLUSH_FN
        def flush_callback(ctx):
            try:
                flush = getattr(file, "flush", None)
                if flush is not None:
                    flush()
                return 0
            except Exception:
                return -1

        @_ffi.GET_POS_FN
        def pos_callback(ctx):
            return pos

        output = _ffi.PaimonVindexOutputFile()
        output.ctx = None
        output.write_fn = write_callback
        output.flush_fn = flush_callback
        output.get_pos_fn = pos_callback

        rc = lib.paimon_vindex_writer_write_index(self._handle, output)
        if rc != 0:
            _check_error("write index failed")

    def close(self):
        if self._handle:
            lib.paimon_vindex_writer_free(self._handle)
            self._handle = None
        self._closed = True

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False

    def __del__(self):
        try:
            self.close()
        except Exception:
            pass


class VectorIndexReader:
    def __init__(self, input):
        self._input = input
        self._closed = False

        @_ffi.READ_AT_FN
        def read_at_callback(ctx, offset, buf, length):
            try:
                chunks = self._input.pread_many([(offset, length)])
                if len(chunks) != 1:
                    return -1
                data = bytes(chunks[0])
                if len(data) != length:
                    return -1
                ctypes.memmove(buf, data, length)
                return 0
            except Exception:
                return -1

        self._read_at_callback = read_at_callback
        input_file = _ffi.PaimonVindexInputFile()
        input_file.ctx = None
        input_file.read_at_fn = self._read_at_callback
        self._handle = lib.paimon_vindex_reader_open(input_file)
        if not self._handle:
            _check_error("failed to open reader")
        self._metadata = self.metadata()

    def _require_open(self):
        if self._closed or not self._handle:
            raise RuntimeError("VectorIndexReader is closed")

    @property
    def index_type(self):
        return self.metadata().index_type

    @property
    def dimension(self):
        return self.metadata().dimension

    @property
    def nlist(self):
        return self.metadata().nlist

    @property
    def total_vectors(self):
        return self.metadata().total_vectors

    def metadata(self):
        self._require_open()
        raw = _ffi.PaimonVindexMetadata()
        rc = lib.paimon_vindex_reader_metadata(self._handle, ctypes.byref(raw))
        if rc != 0:
            _check_error("metadata failed")
        return _metadata_from_ffi(raw)

    def optimize_for_search(self):
        self._require_open()
        rc = lib.paimon_vindex_reader_optimize_for_search(self._handle)
        if rc != 0:
            _check_error("optimize_for_search failed")

    def _filter_args(self, filter_bytes):
        if filter_bytes is None:
            return None, 0, None
        return _bytes_buffer(filter_bytes, "filter_bytes")

    def search(self, query, params: SearchParams, filter_bytes=None):
        self._require_open()
        query = _float32_vector(query, "query")
        if query.shape[0] != self._metadata.dimension:
            raise RuntimeError(
                f"query length {query.shape[0]} does not match index dimension "
                f"{self._metadata.dimension}"
            )
        ffi_params = params.to_ffi()
        ids = np.empty(params.top_k, dtype=np.int64)
        distances = np.empty(params.top_k, dtype=np.float32)

        if filter_bytes is None:
            rc = lib.paimon_vindex_reader_search(
                self._handle,
                query.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                ffi_params,
                ids.ctypes.data_as(ctypes.POINTER(ctypes.c_int64)),
                distances.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                params.top_k,
            )
        else:
            filter_buf, filter_len, _ = self._filter_args(filter_bytes)
            rc = lib.paimon_vindex_reader_search_with_roaring_filter(
                self._handle,
                query.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                ffi_params,
                filter_buf,
                filter_len,
                ids.ctypes.data_as(ctypes.POINTER(ctypes.c_int64)),
                distances.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                params.top_k,
            )
        if rc != 0:
            _check_error("search failed")
        return ids, distances

    def search_batch(self, queries, params: SearchParams, filter_bytes=None):
        self._require_open()
        queries = _float32_matrix(queries, "queries")
        if queries.shape[1] != self._metadata.dimension:
            raise RuntimeError(
                f"queries length {queries.size} does not match nq * dimension "
                f"{queries.shape[0] * self._metadata.dimension}"
            )
        ffi_params = params.to_ffi()
        result_len = queries.shape[0] * params.top_k
        ids = np.empty((queries.shape[0], params.top_k), dtype=np.int64)
        distances = np.empty((queries.shape[0], params.top_k), dtype=np.float32)

        if filter_bytes is None:
            rc = lib.paimon_vindex_reader_search_batch(
                self._handle,
                queries.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                queries.shape[0],
                ffi_params,
                ids.ctypes.data_as(ctypes.POINTER(ctypes.c_int64)),
                distances.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                result_len,
            )
        else:
            filter_buf, filter_len, _ = self._filter_args(filter_bytes)
            rc = lib.paimon_vindex_reader_search_batch_with_roaring_filter(
                self._handle,
                queries.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                queries.shape[0],
                ffi_params,
                filter_buf,
                filter_len,
                ids.ctypes.data_as(ctypes.POINTER(ctypes.c_int64)),
                distances.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
                result_len,
            )
        if rc != 0:
            _check_error("batch search failed")
        return ids, distances

    def close(self):
        if self._handle:
            lib.paimon_vindex_reader_free(self._handle)
            self._handle = None
        self._closed = True

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False

    def __del__(self):
        try:
            self.close()
        except Exception:
            pass


__all__ = [
    "VectorIndexMetadata",
    "VectorIndexReader",
    "VectorIndexTrainer",
    "VectorIndexTraining",
    "VectorIndexWriter",
]
