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

"""Python dynamic-bucket allocation and persistent HASH index execution."""

import random
import struct
import uuid
from dataclasses import dataclass
from typing import Dict, Iterator, List, Set, Tuple

from pypaimon.index.dynamic_bucket import (
    HASH_INDEX, MAX_DYNAMIC_BUCKETS, to_signed_int32, validate_bucket_id, validate_max_buckets,
)
from pypaimon.index.index_file_handler import IndexFileHandler
from pypaimon.index.index_file_meta import IndexFileMeta
from pypaimon.manifest.index_manifest_entry import IndexManifestEntry
from pypaimon.table.row.generic_row import GenericRow

_ADD = 0
_SNAPSHOT_UNSET = object()


def _java_remainder(value: int, divisor: int) -> int:
    remainder = abs(value) % divisor
    return -remainder if value < 0 else remainder


def compute_assigner(
    partition_hash: int,
    key_hash: int,
    num_channels: int,
    num_assigners: int,
) -> int:
    """Mirror Java ``BucketAssigner.computeAssigner``."""
    if num_channels <= 0 or num_assigners <= 0:
        raise ValueError("num_channels and num_assigners must be positive")
    start = abs(_java_remainder(to_signed_int32(partition_hash), num_channels))
    assigner = abs(_java_remainder(to_signed_int32(key_hash), num_assigners))
    return _java_remainder(to_signed_int32(start + assigner), num_channels)


def is_my_bucket(bucket: int, num_assigners: int, assign_id: int) -> bool:
    return bucket % num_assigners == assign_id % num_assigners


def _iter_hashes(table, entry: IndexManifestEntry) -> Iterator[int]:
    meta = entry.index_file
    path = table.path_factory().bucket_index_path(
        tuple(entry.partition.values), entry.bucket, meta
    )
    with table.file_io.new_input_stream(path) as stream:
        remainder = b""
        while True:
            payload = stream.read(64 * 1024)
            if not payload:
                break
            payload = remainder + payload
            aligned_size = len(payload) - len(payload) % 4
            for value in struct.iter_unpack(">i", payload[:aligned_size]):
                yield value[0]
            remainder = payload[aligned_size:]
        if remainder:
            raise RuntimeError(
                f"Corrupt dynamic-bucket HASH index {path}: "
                "expected a multiple of 4 bytes"
            )


class _PartitionIndex:
    def __init__(
        self,
        hash_to_bucket: Dict[int, int],
        bucket_information: Dict[int, int],
        target_bucket_row_number: int,
    ) -> None:
        self.hash_to_bucket = hash_to_bucket
        self.non_full_bucket_information = bucket_information
        self.total_bucket_set = set(bucket_information)
        self.total_bucket_list = list(bucket_information)
        self.target_bucket_row_number = target_bucket_row_number
        self._bucket_upper_bound_reached = False

    def assign(
        self,
        key_hash: int,
        bucket_filter,
        max_buckets_num: int,
        max_bucket_id: int,
    ) -> int:
        return self.assign_with_status(
            key_hash, bucket_filter, max_buckets_num, max_bucket_id
        )[0]

    def assign_with_status(
        self,
        key_hash: int,
        bucket_filter,
        max_buckets_num: int,
        max_bucket_id: int,
    ) -> Tuple[int, bool]:
        validate_max_buckets(max_buckets_num)
        if key_hash in self.hash_to_bucket:
            return self.hash_to_bucket[key_hash], False

        for bucket, row_count in list(self.non_full_bucket_information.items()):
            if row_count < self.target_bucket_row_number:
                self.non_full_bucket_information[bucket] = row_count + 1
                self.hash_to_bucket[key_hash] = bucket
                return bucket, True
            del self.non_full_bucket_information[bucket]

        global_max_bucket_id = (
            MAX_DYNAMIC_BUCKETS if max_buckets_num == -1 else max_buckets_num
        ) - 1
        # Java's occupancy and bucket limit are partition-local. A larger
        # bucket restored from another partition cannot hide a free local ID.
        if not self._bucket_upper_bound_reached:
            for bucket in range(global_max_bucket_id + 1):
                if bucket_filter(bucket) and bucket not in self.total_bucket_set:
                    self.non_full_bucket_information[bucket] = 1
                    self.total_bucket_set.add(bucket)
                    self.total_bucket_list.append(bucket)
                    self.hash_to_bucket[key_hash] = bucket
                    return bucket, True
            if max_buckets_num == -1:
                raise RuntimeError(
                    "No dynamic bucket id remains below Java Short.MAX_VALUE. "
                    "Increase dynamic-bucket.target-row-num."
                )
            # The assigner's ownership and limit are fixed for this partition,
            # so Java remembers exhaustion and reuses an owned bucket directly.
            self._bucket_upper_bound_reached = True

        if not self.total_bucket_list:
            raise RuntimeError(
                "No dynamic bucket is available for this assigner. Reduce the "
                "assigner parallelism or increase dynamic-bucket.max-buckets."
            )
        bucket = random.choice(self.total_bucket_list)
        self.hash_to_bucket[key_hash] = bucket
        return bucket, True


class DynamicBucketAssigner:
    """Restore dynamic-bucket mappings from HASH indexes before assigning."""

    def __init__(
        self,
        table,
        num_channels: int,
        num_assigners: int,
        assign_id: int,
        target_bucket_row_number: int,
        max_buckets_num: int,
        ignore_existing: bool = False,
        snapshot=_SNAPSHOT_UNSET,
    ) -> None:
        validate_max_buckets(max_buckets_num)
        if not 0 <= assign_id < num_channels:
            raise ValueError(
                f"assign_id must be in [0, {num_channels}), got {assign_id}"
            )
        self.table = table
        self.num_channels = num_channels
        self.num_assigners = num_assigners
        self.assign_id = assign_id
        self.target_bucket_row_number = target_bucket_row_number
        self.max_buckets_num = max_buckets_num
        self.ignore_existing = ignore_existing
        self.snapshot = (
            table.snapshot_manager().get_latest_snapshot()
            if snapshot is _SNAPSHOT_UNSET
            else snapshot
        )
        self.max_bucket_id = 0
        self._partition_indexes: Dict[Tuple, _PartitionIndex] = {}

    def assign(self, partition: Tuple, partition_hash: int, key_hash: int) -> int:
        return self.assign_with_status(partition, partition_hash, key_hash)[0]

    def assign_with_status(
        self, partition: Tuple, partition_hash: int, key_hash: int
    ) -> Tuple[int, bool]:
        result = self.assign_batch(
            [partition], [partition_hash], [key_hash]
        )
        return result[0]

    def assign_batch(
        self,
        partitions: List[Tuple],
        partition_hashes: List[int],
        key_hashes: List[int],
    ) -> List[Tuple[int, bool]]:
        if not (
            len(partitions) == len(partition_hashes) == len(key_hashes)
        ):
            raise ValueError(
                "Partition, partition-hash, and key-hash counts must match"
            )
        requested_by_partition: Dict[Tuple, Set[int]] = {}
        normalized_hashes = [to_signed_int32(value) for value in key_hashes]
        for partition, partition_hash, key_hash in zip(
            partitions, partition_hashes, normalized_hashes
        ):
            self._validate_assigner(partition_hash, key_hash)
            requested_by_partition.setdefault(partition, set()).add(key_hash)

        for partition, requested in requested_by_partition.items():
            index = self._partition_indexes.get(partition)
            if index is None:
                index = self._load_partition(
                    partition,
                    requested,
                )
                self._partition_indexes[partition] = index
            else:
                missing = requested.difference(index.hash_to_bucket)
                if missing:
                    self._restore_requested_hashes(
                        partition,
                        missing,
                        index.hash_to_bucket,
                    )

        results = []
        for partition, key_hash in zip(partitions, normalized_hashes):
            index = self._partition_indexes[partition]
            bucket, is_new = index.assign_with_status(
                key_hash,
                lambda value: is_my_bucket(
                    value, self.num_assigners, self.assign_id
                ),
                self.max_buckets_num,
                self.max_bucket_id,
            )
            self.max_bucket_id = max(self.max_bucket_id, bucket)
            results.append((bucket, is_new))
        return results

    def _validate_assigner(self, partition_hash: int, key_hash: int) -> None:
        expected_assigner = compute_assigner(
            partition_hash,
            key_hash,
            self.num_channels,
            self.num_assigners,
        )
        if expected_assigner != self.assign_id:
            raise ValueError(
                f"Record assigner {expected_assigner} does not match writer "
                f"assigner {self.assign_id}"
            )

    def _load_partition(
        self, partition: Tuple, requested_hashes: Set[int]
    ) -> _PartitionIndex:
        if self.ignore_existing:
            return _PartitionIndex({}, {}, self.target_bucket_row_number)
        snapshot = self.snapshot
        if snapshot is None:
            return _PartitionIndex({}, {}, self.target_bucket_row_number)
        entries = IndexFileHandler(self.table).scan(
            snapshot,
            lambda entry: entry.index_file.index_type == HASH_INDEX
            and tuple(entry.partition.values) == partition,
        )
        entries_by_bucket = {}
        for entry in entries:
            validate_bucket_id(entry.bucket)
            previous = entries_by_bucket.get(entry.bucket)
            if previous is not None:
                raise RuntimeError(
                    "Found multiple dynamic-bucket HASH indexes for partition "
                    f"{partition}, bucket {entry.bucket}: "
                    f"{[previous.index_file.file_name, entry.index_file.file_name]}"
                )
            entries_by_bucket[entry.bucket] = entry

        data_buckets = self._active_data_buckets(partition, snapshot)
        missing_buckets = data_buckets.difference(entries_by_bucket)
        if missing_buckets:
            raise RuntimeError(
                f"Dynamic-bucket partition {partition} has data files but no "
                "complete HASH index for buckets "
                f"{sorted(missing_buckets)}. Rewrite the partition before "
                "performing incremental writes."
            )

        hash_to_bucket: Dict[int, int] = {}
        bucket_information: Dict[int, int] = {}
        for entry in entries:
            self.max_bucket_id = max(self.max_bucket_id, entry.bucket)
            if is_my_bucket(
                entry.bucket, self.num_assigners, self.assign_id
            ):
                bucket_information[entry.bucket] = entry.index_file.row_count
        remaining = set(requested_hashes)
        for entry in entries:
            if not remaining:
                break
            for key_hash in _iter_hashes(self.table, entry):
                if key_hash in remaining:
                    hash_to_bucket[key_hash] = entry.bucket
                    remaining.remove(key_hash)
                    if not remaining:
                        break
        return _PartitionIndex(
            hash_to_bucket,
            bucket_information,
            self.target_bucket_row_number,
        )

    def _restore_requested_hashes(
        self,
        partition: Tuple,
        requested_hashes: Set[int],
        hash_to_bucket: Dict[int, int],
    ) -> None:
        if self.ignore_existing or not requested_hashes:
            return
        snapshot = self.snapshot
        if snapshot is None:
            return
        entries = IndexFileHandler(self.table).scan(
            snapshot,
            lambda entry: entry.index_file.index_type == HASH_INDEX
            and tuple(entry.partition.values) == partition,
        )
        remaining = set(requested_hashes)
        for entry in entries:
            validate_bucket_id(entry.bucket)
            for key_hash in _iter_hashes(self.table, entry):
                if key_hash not in remaining:
                    continue
                hash_to_bucket[key_hash] = entry.bucket
                remaining.remove(key_hash)
                if not remaining:
                    return

    def _active_data_buckets(self, partition: Tuple, snapshot) -> Set[int]:
        if snapshot is None:
            return set()
        from pypaimon.execution.python.write.bucket_metadata import dynamic_bucket_data_buckets
        return dynamic_bucket_data_buckets(self.table, partition, snapshot)


@dataclass
class DynamicBucketIndexChanges:
    additions: List[IndexManifestEntry]
    deletions: List[IndexManifestEntry]


class DynamicBucketIndexMaintainer:
    """Maintain one complete HASH index file for every modified bucket."""

    def __init__(
        self,
        table,
        ignore_existing: bool = False,
        snapshot=_SNAPSHOT_UNSET,
    ) -> None:
        self.table = table
        self.ignore_existing = ignore_existing
        self.snapshot = (
            table.snapshot_manager().get_latest_snapshot()
            if snapshot is _SNAPSHOT_UNSET
            else snapshot
        )
        self.base_snapshot_id = (
            self.snapshot.id if self.snapshot is not None else 0
        )
        self._states: Dict[
            Tuple[Tuple, int], Tuple[Set[int], bool]
        ] = {}
        self._new_paths: List[str] = []

    def notify_new_record(
        self, partition: Tuple, bucket: int, key_hash: int
    ) -> None:
        key = (partition, bucket)
        state = self._states.get(key)
        if state is None:
            state = (self._load_bucket(partition, bucket), False)
        hashes, modified = state
        previous_size = len(hashes)
        hashes.add(to_signed_int32(key_hash))
        self._states[key] = (hashes, modified or len(hashes) != previous_size)

    def prepare_commit(self) -> Dict[Tuple[Tuple, int], DynamicBucketIndexChanges]:
        changes: Dict[Tuple[Tuple, int], DynamicBucketIndexChanges] = {}
        prepared_states = {}
        for key, (hashes, modified) in self._states.items():
            if not modified:
                continue
            partition, bucket = key
            new_entry = self._write_index(partition, bucket, hashes)
            changes[key] = DynamicBucketIndexChanges(
                additions=[new_entry],
                # Java sends only the full new HASH file. BucketedCombiner
                # replaces the previous entry by partition and bucket.
                deletions=[],
            )
            prepared_states[key] = (hashes, False)
        # A failed bucket must not make a retry forget earlier additions.
        self._states.update(prepared_states)
        return changes

    def release_prepared(self) -> None:
        """Release files after their commit messages leave writer ownership."""
        self._new_paths.clear()

    def abort(self) -> None:
        for path in self._new_paths:
            self.table.file_io.delete_quietly(path)
        self._new_paths.clear()

    def _load_bucket(
        self, partition: Tuple, bucket: int
    ) -> Set[int]:
        """Load a complete bucket index for full-file replacement.

        This matches Java's HASH index lifecycle. A modified bucket therefore
        incurs O(bucket size) read memory and IO until an incremental index
        format is introduced.
        """
        if self.ignore_existing:
            return set()
        snapshot = self.snapshot
        if snapshot is None:
            return set()
        entries = IndexFileHandler(self.table).scan(
            snapshot,
            lambda entry: entry.index_file.index_type == HASH_INDEX
            and tuple(entry.partition.values) == partition
            and entry.bucket == bucket,
        )
        if len(entries) > 1:
            raise RuntimeError(
                "Found multiple dynamic-bucket HASH indexes for partition "
                f"{partition}, bucket {bucket}: "
                f"{[entry.index_file.file_name for entry in entries]}"
            )
        if not entries:
            return set()
        return set(_iter_hashes(self.table, entries[0]))

    def _write_index(
        self, partition: Tuple, bucket: int, hashes: Set[int]
    ) -> IndexManifestEntry:
        file_name = f"index-{uuid.uuid4()}-0"
        path, external = self.table.path_factory().new_bucket_index_path(
            partition, bucket, file_name
        )
        self.table.file_io.check_or_mkdirs(path.rsplit("/", 1)[0])
        payload = b"".join(struct.pack(">i", value) for value in sorted(hashes))
        try:
            with self.table.file_io.new_output_stream(path) as stream:
                stream.write(payload)
        except Exception:
            self.table.file_io.delete_quietly(path)
            raise
        self._new_paths.append(path)

        meta = IndexFileMeta(
            index_type=HASH_INDEX,
            file_name=path.rsplit("/", 1)[-1],
            file_size=self.table.file_io.get_file_size(path),
            row_count=len(hashes),
            external_path=path if external else None,
        )
        return IndexManifestEntry(
            kind=_ADD,
            partition=GenericRow(
                list(partition), self.table.partition_keys_fields
            ),
            bucket=bucket,
            index_file=meta,
        )
