# -*- coding: utf-8 -*-
from __future__ import absolute_import

from .client import client

import logging
logger = logging.getLogger('solvebio')


class Annotator(object):
    """
    Runs the synchronous annotate endpoint against
    batches of results from a query.
    """
    CHUNK_SIZE = 100

    # Allows pre-setting a SolveClient
    _client = None

    def __init__(self, fields, include_errors=False, **kwargs):
        self._client = kwargs.pop('client', None) or self._client or client

        self.buffer = []
        self.fields = fields
        self.include_errors = include_errors
        self.annotator_params = kwargs
        self.chunk_size = kwargs.get('chunk_size', self.CHUNK_SIZE)

    def annotate(self, records, **kwargs):
        """Annotate a set of records with stored fields.

        Args:
            records: A list or iterator (can be a Query object)
            chunk_size: The number of records to annotate at once (max 500).

        Returns:
            A generator that yields one annotated record at a time.
        """
        chunk_size = kwargs.get('chunk_size', self.chunk_size)

        chunk = []
        for i, record in enumerate(records):
            chunk.append(record)
            if (i + 1) % chunk_size == 0:
                for r in self._execute(chunk):
                    yield r
                chunk = []

        if chunk:
            for r in self._execute(chunk):
                yield r
            chunk = []

    def _execute(self, chunk):
        data = {
            'records': chunk,
            'fields': self.fields,
            'include_errors': self.include_errors,
            'annotator_params': self.annotator_params
        }

        for r in self._client.post('/v1/annotate', data)['results']:
            yield r


class Expression(object):
    """Runs a single SolveBio expression."""

    # Allows pre-setting a SolveClient
    _client = None

    def __init__(self, expr, **kwargs):
        self.expr = expr
        self._client = kwargs.get('client') or self._client or client

    def evaluate(self, data=None, data_type='string', is_list=False):
        """Evaluates the expression with the provided context and format."""
        payload = {
            'data': data,
            'expression': self.expr,
            'data_type': data_type,
            'is_list': is_list
        }
        res = self._client.post('/v1/evaluate', payload)
        return res['result']

    def __repr__(self):
        return '<Expression "{0}">'.format(self.expr)

@@ -385,30 +385,8 @@
 lds,
- include_errors=False,
  **k
@@ -385,32 +385,32 @@
 lds, **kwargs):%0A
+
         self._cl
@@ -524,24 +524,25 @@
  fields%0A
+%0A
         
 self.inc
@@ -537,45 +537,276 @@
     
-self.include_errors = include_errors%0A
+# Pop annotator_params from kwargs%0A        annotator_param_keys = %5B%0A            'annotator',%0A            'debug',%0A            'include_errors',%0A        %5D%0A        self.annotator_params = %7B%7D%0A        for key in annotator_param_keys:%0A            if key in kwargs:%0A        
     
@@ -830,16 +830,21 @@
 r_params
+%5Bkey%5D
  = kwarg
@@ -840,24 +840,34 @@
 ey%5D = kwargs
+.pop(key)%0A
 %0A        sel
@@ -868,34 +868,134 @@
    self.
-chunk_size = kwarg
+data = kwargs%0A%0A        # Unify annotator chunk_size and request chunk_size%0A        # self.chunk_size = annotator_param
 s.get('c
@@ -1390,33 +1390,105 @@
     
-chunk_size = kwargs.get('
+# Update annotator_params with any kwargs%0A        self.annotator_params.update(**kwargs)%0A        
 chun
@@ -1497,26 +1497,66 @@
 size
-',
+ =
  self.
-chunk_size
+annotator_params.get('chunk_size', self.CHUNK_SIZE
 )%0A%0A 
@@ -2022,59 +2022,8 @@
 ds,%0A
-            'include_errors': self.include_errors,%0A
     
@@ -2071,16 +2071,47 @@
 r_params
+,%0A            'data': self.data
 %0A       

update annotator_params and add data param (closes #271)