#
# # 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>
#
"""S3 download operations."""

from __future__ import annotations

from pathlib import Path
from typing import Any

from botocore.client import BaseClient  # type: ignore[import-not-found]


def download_file(
    s3_client: BaseClient,
    bucket_name: str,
    key: str,
    destination: str,
    *,
    exist_ok: bool = False,
) -> None:
    """Download s3 object as a file.

    Download object from s3 `key` into `destination`, with error handling.

    Parameters
    ----------
    s3_client:
        s3 client instance.
    bucket_name: str
        The s3 bucket name.
    key: str
        The s3 key to check.
    destination: str
        Path to download the file into
    exist_ok: bool, optional
        If False, raise an error if a file at `destination` already exists
        before performing the download. If True, do not raise an error.
        Default=False.

    Returns:
    -------
    Nothing
    """
    if (not exist_ok) and Path(destination).exists():
        msg = (
            "Unable to perform copy: "
            f"file already exists at {destination} "
            "and exist_ok=False. Set exist_ok=True to allow overwrite."
        )
        raise FileExistsError(msg)
    response = s3_client.download_file(bucket_name, key, destination)
    if response is not None:
        msg = f"download of {key} to {destination} failed: {response}"
        raise RuntimeError(msg)
    if not Path(destination).exists():
        msg = f"boto3 reported no errors but file not visible after download: {destination} doesn't exist"
        raise RuntimeError(msg)


def stream_file(s3_client: Any, bucket_name: str, key: str) -> Any:
    """Open s3 object as bytes.

    Stream object from s3 `key` as bytes.

    Parameters
    ----------
    s3_client:
        s3 client instance.
    bucket_name: str
        The s3 bucket name.
    key: str
        The s3 key to check.

    Returns:
    -------
    bytes
    """
    response = s3_client.get_object(Bucket=bucket_name, Key=key)
    return response["Body"]
