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

from __future__ import annotations

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

from peak.tools.s3.exists import object_exists


def copy(
    s3_client: BaseClient,
    bucket_name: str,
    source_key: str,
    destination_key: str,
    *,
    exist_ok: bool = False,
) -> None:
    """Copy an object within the S3 bucket.

    Copies object from `source_key` to `destination_key`.

    Parameters
    ----------
    s3_client:
        s3 client instance.
    bucket_name: str
        The s3 bucket name. This is used for both the source key and
        destination key.
    source_key: str
        The s3 key of the source object.
    destination_key: str
        The s3 key of the destination (copied) object.
    exist_ok: bool, optional
        If False, raise an error if an object already exists at
        `destination_key` before perofmring the copy. If True, do not raise
        an error. Default=False.

    Returns:
    -------
    Nothing
    """
    if (not exist_ok) and object_exists(s3_client, bucket_name, destination_key):
        msg = (
            "Unable to perform copy: "
            f"object already exists at {destination_key} "
            "and exist_ok=False. Set exist_ok=True to allow overwrite."
        )
        raise FileExistsError(msg)

    copy_source = {"Bucket": bucket_name, "Key": source_key}
    s3_client.copy(copy_source, bucket_name, destination_key)
