from oci.object_storage import ObjectStorageClient
from wpaudit.providers.oci.authentication_strategy import OracleCredentials
from oci.pagination import list_call_get_all_results

from wpaudit.providers.utils import run_concurrently
from wpaudit.core.console import print_exception


class ObjectStorageFacade:
    def __init__(self, credentials: OracleCredentials):
        self._credentials = credentials
        self._client = ObjectStorageClient(self._credentials.config)

    async def get_namespace(self):
        try:
            response = await run_concurrently(
                lambda: list_call_get_all_results(self._client.get_namespace))
            # for some reason it returns a list of chars instead of a string
            return ''.join(response.data)
        except Exception as e:
            print_exception(f'Failed to get Object Storage namespace: {e}')
            return None

    async def get_bucket_details(self, namespace, bucket_name):
        try:
            response = await run_concurrently(
                lambda: self._client.get_bucket(namespace, bucket_name)
            )
            return response.data
        except Exception as e:
            print_exception(f'Failed to get Object Storage bucket details: {e}')
            return None

    async def get_buckets(self, namespace):
        try:
            response = await run_concurrently(
                lambda: list_call_get_all_results(self._client.list_buckets, namespace, self._credentials.get_scope()))
            return response.data
        except Exception as e:
            print_exception(f'Failed to get Object Storage buckets: {e}')
            return []

    async def get_bucket_objects(self, namespace, bucket_name):
        try:
            response = await run_concurrently(
                lambda: list_call_get_all_results(self._client.list_objects, namespace, bucket_name))
            return response.data
        except Exception as e:
            print_exception(f'Failed to get Object Storage bucket objects: {e}')
            return []
