from ..baseapi import BaseApi


class Assets(BaseApi):
    def __init__(self, *args, **kwargs):
        """
        Initialize the endpoint.
        """
        self.endpoint = 'assets'
        super().__init__(*args, **kwargs)

    def list_asset_groups(self) -> dict:
        """
        List asset groups.
        """
        response_json, _ = self._client._get(self._build_path(property='assetgroups'))
        return response_json

    def search(self, querystring: str, queryparams: dict = None) -> dict:
        """
        List entities by search query. `querystring` parameter takes the quick search syntax documented here:
        https://community.widen.com/collective/s/article/How-do-I-search-for-assets
        """
        if not queryparams:
            queryparams = {}

        queryparams.update({
            'query': querystring,
            'scroll': True,
        })

        response_json, _ = self._client._get(self._build_path(property='search', queryparams=queryparams))

        if self._client.enabled:
            if response_json['scroll_id']:
                for items in self._scroll(response_json['scroll_id'], expand=queryparams.get('expand', '')):
                    response_json['items'].extend(items)

        return response_json

    def _scroll(self, scroll_id: str, expand: str) -> list:
        """
        Fetch all remaining scroll results for a given response, returning an iterator with the results.
        """
        queryparams = {
            'scroll_id': scroll_id,
            'expand': expand,
        }

        result, _ = self._client._get(self._build_path(property='search/scroll', queryparams=queryparams))

        if self._client.enabled:
            items = result['items']

            while items:
                yield result['items']
                result, _ = self._client._get(self._build_path(property='search/scroll', queryparams=queryparams))
                items = result['items']
        else:
            return []

    def get_metadata(self, key: str) -> dict:
        """
        Get metadata for an asset.
        """
        response_json, _ = self._client._get(self._build_path(key=key, property='metadata'))
        return response_json

    def update_metadata(self, key: str, metadata: dict) -> dict:
        """
        Update metadata for an asset. Only keys passed will be updated.
        """
        patch = {
            'patch': ','.join(metadata['fields'].keys())
        }

        response_json, _ = self._client._put(self._build_path(key=key, property='metadata', queryparams=patch), metadata)
        return response_json

    def get_security(self, key: str) -> dict:
        """
        Get security for an asset.
        """
        response_json, _ = self._client._get(self._build_path(key=key, property='security'))
        return response_json

    def update_security(self, key: str, security: dict) -> dict:
        """
        Update security for an asset. Only keys passed will be updated.
        """
        patch = {
            'patch': ','.join(security.keys()),
        }

        response_json, _ = self._client._put(self._build_path(key=key, property='security', queryparams=patch), security)
        return response_json

    def rename(self, key: str, filename: str) -> dict:
        """
        Renames an assets's filename.
        """
        response_json, _ = self._client._put(
            self._build_path(key=key, property='filename'),
            {'filename': filename}
        )
        return response_json

    def delete(self, key: str) -> dict:
        """
        Delete an asset.
        """
        response_json, _ = self._client._delete(self._build_path(key=key))
        return response_json
