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

import itertools

from future.builtins import next, object
from future.builtins.iterators import filter
from future.utils import python_2_unicode_compatible, raise_from

from .utils import HolviObject


class Category(HolviObject):
    """Baseclass for income/expense categories, do not instantiate directly"""

    def __init__(self, api, jsondata=None, **kwargs):
        self._fetch_method = api.get_category
        super(Category, self).__init__(api, jsondata, **kwargs)


class IncomeCategory(Category):
    """This represents an income category in the Holvi system"""
    pass


class ExpenseCategory(Category):
    """This represents an expense category in the Holvi system"""
    pass


@python_2_unicode_compatible
class CategoriesAPI(object):
    """Handles the operations on income/expense categories, instantiate with a Connection object"""
    # Currently only read-only access via the open budget api
    base_url_fmt = 'pool/{pool}/openbudget/'

    def __init__(self, connection):
        self.connection = connection
        self.base_url = str(connection.base_url_fmt + self.base_url_fmt).format(pool=connection.pool)

    def list_income_categories(self):
        """Lists all income categories in the system"""
        url = self.base_url
        obdata = self.connection.make_get(url)
        #print("Got obdata=%s" % obdata)
        ret = []
        for icjson in obdata['income_categories']:
            ret.append(IncomeCategory(self, icjson))
        return ret

    def list_expense_categories(self):
        """Lists all expense categories in the system"""
        url = self.base_url
        obdata = self.connection.make_get(url)
        #print("Got obdata=%s" % obdata)
        ret = []
        for ecjson in obdata['expense_categories']:
            ret.append(ExpenseCategory(self, ecjson))
        return ret

    def get_category(self, code):
        """Gets category with given code

        NOTE: Filters the list of income and expense categories in this end due to
        API limitations"""
        candidates = filter(lambda c: c.code == code, itertools.chain(self.list_income_categories(), self.list_expense_categories()))
        if not candidates:
            return None
        return next(candidates)

@@ -256,16 +256,45 @@
 viObject
+, HolviObjectList, JSONObject
 %0A%0A%0Aclass
@@ -781,16 +781,414 @@
  pass%0A%0A%0A
+class CategoryList(HolviObjectList):%0A%0A    def _get_size(self):%0A        self.size = len(self.jsondata%5Bself._key%5D)%0A%0A    def _get_iter(self):%0A        self._iter = iter(self.jsondata%5Bself._key%5D)%0A%0A%0Aclass IncomeCategoryList(CategoryList):%0A    _klass = IncomeCategory%0A    _key = %22income_categories%22%0A%0A%0Aclass ExpenseCategoryList(CategoryList):%0A    _klass = ExpenseCategory%0A    _key = %22expense_categories%22%0A%0A%0A
 @python_
@@ -1802,180 +1802,47 @@
     
-#print(%22Got obdata=%25s%22 %25 obdata)%0A        ret = %5B%5D%0A        for icjson in obdata%5B'i
+return I
 ncome
-_c
+C
 ategor
-ies'%5D:%0A            ret.append(IncomeCategory(self, icjson))%0A        return ret
+yList(obdata, self)
 %0A%0A  
@@ -2022,182 +2022,48 @@
     
-#print(%22Got obdata=%25s%22 %25 obdata)%0A        ret = %5B%5D%0A        for ecjson in obdata%5B'e
+return E
 xpense
-_c
+C
 ategor
-ies'%5D:%0A            ret.append(ExpenseCategory(self, ecjson))%0A        return ret
+yList(obdata, self)
 %0A%0A  

Refactor categories lists to iterators