from math import ceil

from pylons import config

from ckan import model
from ckan.plugins import toolkit
from ckan.lib import helpers
from ckanext.issues.model import IssueFilter
from ckanext.issues import model as issuemodel

ISSUES_PER_PAGE = (15, 30, 50)

log = __import__('logging').getLogger(__name__)


def replace_url_param(new_params, alternative_url=None, controller=None,
                      action=None, extras=None):
    '''
    replace existing parameters with new ones

    controller action & extras (dict) are used to create the base url via
    :py:func:`~ckan.lib.helpers.url_for` controller & action default to the
    current ones

    This can be overriden providing an alternative_url, which will be used
    instead.
    '''
    params_cleaned = [(k, v) for k, v in toolkit.request.params.items()
                      if k not in new_params.keys()]
    params = set(params_cleaned)
    if new_params:
        params |= set(new_params.items())
    if alternative_url:
        return helpers._url_with_params(alternative_url, params)
    return helpers._create_url_with_params(params=params,
                                           controller=controller,
                                           action=action, extras=extras)


class Pagination(object):
    def __init__(self, page, per_page, total_count, show_left=2, show_right=2):
        self.page = page
        self.per_page = per_page
        self.total_count = total_count
        self.show_left = show_left
        self.show_right = show_right

    @property
    def pages(self):
        return int(ceil(self.total_count / float(self.per_page)))

    @property
    def has_previous(self):
        return self.page > 1

    @property
    def has_next(self):
        return self.page < self.pages

    @property
    def show_previous(self):
        return self.page > 1 + self.show_left

    @property
    def show_next(self):
        return self.page < self.pages - self.show_right

    def iter_pages(self):
        for i in range(self.page - self.show_left,
                       self.page + self.show_right + 1):
            if i > 0 and i <= self.pages:
                yield i


def get_issue_filter_types():
    return [(f.value, k) for k, f in IssueFilter.__members__.items()]


def get_issues_per_page():
    try:
        issues_per_page = [int(i) for i in
                           config['ckan.issues.issues_per_page']]
    except (ValueError, KeyError):
        issues_per_page = ISSUES_PER_PAGE
    return issues_per_page


def issues_enabled(dataset):
    datasets_with_issues_enabled = set(toolkit.aslist(
        config.get('ckanext.issues.enabled_for_datasets')
    ))
    # if the config option 'ckanext.issues.enabled_for_dataset' is
    # set with a list of datasets, only enabled for the listed datasets
    if datasets_with_issues_enabled:
        if dataset['name'] in datasets_with_issues_enabled:
            return True
    else:
        extras = dataset.get('extras', [])
        for extra in extras:
            if extra.get('key') == 'issues_enabled':
                return toolkit.asbool(extra.get('value'))
        else:
            return toolkit.asbool(
                config.get('ckanext.issues.enabled_per_dataset_default', True)
            )


def issues_list(dataset_ref, status=issuemodel.ISSUE_STATUS.open):
    '''
    Returns list of issue dicts.

    This is just basic - no options for sorting, closed issues, abuse. No
    pagination. For those, use the issues home page.
    '''
    if status not in issuemodel.ISSUE_STATUS:
        log.error('issues_list status must be open or closed - got %s', status)
        status = 'open'
    params = dict(dataset_id=dataset_ref,
                  status=getattr(issuemodel.ISSUE_STATUS, status),
                  sort='newest',
                  visibility=None,
                  q='')

    issues = toolkit.get_action('issue_search')(data_dict=params)
    return issues


def issues_user_has_reported_issue(user, abuse_reports):
    user_obj = model.User.get(user)
    if user_obj:
        return user_obj.id in abuse_reports
    else:
        return False


def get_issue_subject(issue):
    dataset = model.Package.get(issue['dataset_id'])
    return toolkit._(
        '[{dataset}] {issue_title} #{issue_number}'.format(
            dataset=dataset.title,
            issue_title=issue['title'],
            issue_number=issue['number'],
        )
    )

@@ -740,24 +740,57 @@
 ad.%0A    '''%0A
+    from urllib import urlencode%0A
     params_c
@@ -1077,32 +1077,33 @@
 ve_url, params)%0A
+%0A
     return helpe
@@ -1101,192 +1101,67 @@
 urn 
-helpers._create_url_with_params(params=params,%0A                                           controller=controller,%0A                                           action=action, extras=extras
+u%22%7B%7D?%7B%7D%22.format(toolkit.request.path, urlencode(new_params)
 )%0A%0A%0A

Simplify the url generation