from platypush.plugins import action
from platypush.plugins.google import GooglePlugin


class GoogleFitPlugin(GooglePlugin):
    """
    Google Fit plugin.
    """

    scopes = [
        'https://www.googleapis.com/auth/fitness.activity.read',
        'https://www.googleapis.com/auth/fitness.body.read',
        'https://www.googleapis.com/auth/fitness.body_temperature.read',
        'https://www.googleapis.com/auth/fitness.heart_rate.read',
        'https://www.googleapis.com/auth/fitness.sleep.read',
        'https://www.googleapis.com/auth/fitness.location.read',
    ]

    def __init__(self, user_id='me', *args, **kwargs):
        """
        :param user_id: Default Google user_id (default: 'me', default
            configured account user)
        :type user_id: str or int
        """

        super().__init__(scopes=self.scopes, *args, **kwargs)
        self.user_id = user_id

    @action
    def get_data_sources(self, user_id=None):
        """
        Get the available data sources for the specified user_id
        """

        service = self.get_service(service='fitness', version='v1')
        sources = (
            service.users().dataSources().list(userId=user_id or self.user_id).execute()
        )

        return sources['dataSource']

    @action
    def get_data(self, data_source_id, user_id=None, limit=None):
        """
        Get raw data for the specified data_source_id

        :param data_source_id: Data source ID, see `get_data_sources`
        :type data_source_id: str
        :param user_id: Target user ID (default: configured user).
        :param limit: Maximum number of items to return.
        """

        service = self.get_service(service='fitness', version='v1')
        kwargs = {
            'dataSourceId': data_source_id,
            'userId': user_id or self.user_id,
        }

        if limit:
            kwargs['limit'] = limit
        data_points = []

        for data_point in (
            service.users()
            .dataSources()
            .dataPointChanges()
            .list(**kwargs)
            .execute()
            .get('insertedDataPoint', [])
        ):
            data_point['startTime'] = float(data_point.pop('startTimeNanos')) / 1e9
            data_point['endTime'] = float(data_point.pop('endTimeNanos')) / 1e9
            data_point['modifiedTime'] = (
                float(data_point.pop('modifiedTimeMillis')) / 1e6
            )
            values = []

            for value in data_point.pop('value'):
                if value.get('intVal') is not None:
                    value = value['intVal']
                elif value.get('fpVal') is not None:
                    value = value['fpVal']
                elif value.get('stringVal') is not None:
                    value = value['stringVal']
                elif value.get('mapVal'):
                    value = {
                        v['key']: v['value'].get(
                            'intVal',
                            v['value'].get('fpVal', v['value'].get('stringVal')),
                        )
                        for v in value['mapVal']
                    }

                values.append(value)

            data_point['values'] = values
            data_points.append(data_point)

        return data_points


# vim:sw=4:ts=4:et:
