"""Tasks related to feed_items"""
from __future__ import print_function

from distribution import app
from distribution.models.feed import FeedItem
from elasticsearch.helpers import scan
from invoke import task

from .utils import confirm, colored, Colors, pluralize


def _search_by_content_type(content_type, index_name, doc_type):
    escaped_ct = content_type.replace(':', '\\:')
    query = {
        "query": {
            "query_string": {
                "default_operator": "AND",
                "query": "content_type:{}".format(escaped_ct)
            }
        }
    }

    return scan(
        FeedItem.manager.backend.client,
        query,
        index=index_name,
        doc_type=doc_type,
        raise_on_error=False
    )


@task(help={
    'from_ct': "Content type to be renamed",
    'to_ct': 'New content type.',
    'dry_run': 'No actions will be taken.',
    'print_ids': "Print affected item ids.",
})
def rename_ct(ctx, from_ct, to_ct, dry_run=False, print_ids=False):
    """Update the content type of the matching feed items."""
    actions = []
    index_name = app.config.get('ELASTICSEARCH_FEED_INDEX_NAME', 'distribution_feed')
    doc_type = FeedItem.manager.doc_type

    generator = _search_by_content_type(from_ct, index_name, doc_type)

    print(colored('Renaming content_type: {} -> {}'.format(from_ct, to_ct), Colors.OKBLUE))
    for item in generator:

        if item['_source']['content_type'] == from_ct:
            if print_ids:
                print('-- id: {}, ct: {}'.format(
                    item['_source']['id'], item['_source']['content_type']))
            item['_source']['content_type'] = to_ct
            actions.append({'_op_type': 'index',
                            '_index': index_name,
                            '_type': doc_type,
                            '_id': item['_id'],
                            '_source': item['_source']})

    if not actions:
        print(colored('No matching items found.', Colors.WARNING))
        return

    actions_len = len(actions)

    print(colored('{} {} would be affected.'.format(
        actions_len, pluralize('item', actions_len)), Colors.OKBLUE))
    if not dry_run and confirm("==> Do you wish to proceed?"):
        print('Executing {} {}'.format(actions_len, pluralize('action', actions_len)))
        FeedItem.manager.backend.bulk(actions)
        print(colored('Done!', Colors.OKGREEN))


def _move_docs_by_content_type(content_type, to_doc_type, dry_run=False, print_ids=False):
    """Move documents from a document type to another."""
    actions = []
    index_name = app.config.get('ELASTICSEARCH_FEED_INDEX_NAME', 'distribution_feed')
    doc_type = FeedItem.manager.doc_type

    generator = _search_by_content_type(content_type, index_name, doc_type)

    print(colored('Moving {0} in {1} to {2}'.format(content_type, doc_type, to_doc_type), Colors.OKBLUE))
    for item in generator:

        if item['_source']['content_type'] == content_type:
            if print_ids:
                print('-- id: {}, ct: {}'.format(
                    item['_source']['id'], item['_source']['content_type']))
            actions.append({'_op_type': 'index',
                            '_index': index_name,
                            '_type': to_doc_type,
                            '_id': item['_id'],
                            '_source': item['_source']})
            actions.append({'_op_type': 'delete',
                            '_index': index_name,
                            '_type': doc_type,
                            '_id': item['_id']})

    if not actions:
        print(colored('No matching items found.', Colors.WARNING))
        return

    actions_len = len(actions)

    print(colored('{} {} would be affected.'.format(
        actions_len, pluralize('item', actions_len)), Colors.OKBLUE))
    if not dry_run and confirm("==> Do you wish to proceed?"):
        print('Executing {} {}'.format(actions_len, pluralize('action', actions_len)))
        FeedItem.manager.backend.bulk(actions)
        print(colored('Done!', Colors.OKGREEN))


@task(help={
    'dry_run': 'No actions will be taken.',
    'print_ids': "Print affected item ids.",
})
def move_media_models(ctx, dry_run=False, print_ids=False):
    """Move media documents to the corresponding document type."""
    _move_docs_by_content_type('media:image', 'mediaimage', dry_run, print_ids)
    _move_docs_by_content_type('media:photo', 'mediaphoto', dry_run, print_ids)
    _move_docs_by_content_type('media:video', 'mediavideo', dry_run, print_ids)
