#
# # Copyright © 2026 Peak AI Limited. or its affiliates. All Rights Reserved.
# #
# # Licensed under the Apache License, Version 2.0 (the "License"). You
# # may not use this file except in compliance with the License. A copy of
# # the License is located at:
# #
# # https://github.com/PeakBI/peak-sdk/blob/main/LICENSE
# #
# # or in the "license" file accompanying this file. This file 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.
# #
# # This file is part of the peak-sdk.
# # see (https://github.com/PeakBI/peak-sdk)
# #
# # You should have received a copy of the APACHE LICENSE, VERSION 2.0
# # along with this program. If not, see <https://apache.org/licenses/LICENSE-2.0>
#
"""Utility functions for deploying individual blocks."""

from __future__ import annotations

from typing import Any

from peak.press import blocks
from peak.press.wrappers.deploy.config.deployment_config import find_deployment
from peak.press.wrappers.deploy.utils.parameters_utils import parse_build_and_run_parameters
from peak.tools.logging import LogLevel, PeakLogger, get_logger

logger: PeakLogger = get_logger(level=LogLevel.INFO)


def _get_blocks_client() -> Any:
    """Get the blocks client lazily."""
    return blocks.get_client()


def fetch_block_config(block_spec_id: str, block_version: str) -> tuple[dict[str, Any], dict[str, Any]]:
    """Fetch block configuration and parameters.

    Args:
        block_spec_id: The block specification ID
        block_version: The block version

    Returns:
        Tuple of (block_parameters, block_metadata)
    """
    blocks_client = _get_blocks_client()
    block_spec_release_description = blocks_client.describe_spec_release(
        spec_id=block_spec_id,
        version=block_version,
    )

    block_parameters = parse_build_and_run_parameters(block_spec_release_description["parameters"])

    block_spec_description = blocks_client.describe_spec(
        spec_id=block_spec_id,
    )
    block_metadata = block_spec_description["metadata"]

    return block_parameters, block_metadata


def update_existing_block_deployment(deployment_id: str, revision_body: dict[str, Any]) -> None:
    """Update an existing block deployment with a new revision.

    Args:
        deployment_id: The deployment ID to update
        revision_body: The revision configuration

    Raises:
        ValueError: If revision creation fails
        KeyError: If required keys are missing
        RuntimeError: If deployment update fails
    """
    blocks_client = _get_blocks_client()
    try:
        blocks_client.create_deployment_revision(
            deployment_id=deployment_id,
            body=revision_body,
        )
        logger.info("✅ Successfully updated the block deployment with id: %s", deployment_id)
    except (ValueError, KeyError, RuntimeError):
        logger.exception("Failed to create the block deployment revision")
        raise


def create_new_block_deployment(final_body: dict[str, Any]) -> None:
    """Create a new block deployment.

    Args:
        final_body: The deployment configuration

    Raises:
        ValueError: If deployment creation fails
        KeyError: If required keys are missing
        RuntimeError: If deployment fails
    """
    blocks_client = _get_blocks_client()
    try:
        blocks_client.create_deployment(
            body=final_body,
        )
        logger.info("✅ Successfully deployed the block.")
    except (ValueError, KeyError, RuntimeError):
        logger.exception("Failed to create the new block deployment")
        raise


def prepare_block_revision_body(final_body: dict[str, Any]) -> dict[str, Any]:
    """Prepare the revision body for block deployment updates.

    Args:
        final_body: The final deployment configuration

    Returns:
        Revision body for creating deployment revisions
    """
    return {
        "parameters": final_body["parameters"],
        "revision": final_body["revision"],
        "release": final_body["spec"]["release"],
    }


def find_block_deployment(deployments: list[dict[str, Any]], spec_id: str) -> dict[str, Any] | None:
    """Find a block deployment matching the given spec ID.

    Args:
        deployments: List of deployment dictionaries
        spec_id: The spec ID to search for

    Returns:
        Matching deployment dict, or None if not found
    """
    return find_deployment(deployments, spec_id)
