# -*- coding: utf-8 -*-

from elasticsearch.exceptions import NotFoundError

from tests import TestElasticmock, INDEX_NAME, DOC_TYPE, BODY, DOC_ID


class TestUpdate(TestElasticmock):

    def test_should_partial_update_existing_document(self):
        indexed = dict(BODY)
        indexed.update({
            'text': 'Original',
            'meta': {
                'tags': ['search', 'mock'],
                'count': 1
            }
        })

        data = self.es.index(index=INDEX_NAME, doc_type=DOC_TYPE, body=indexed)
        document_id = data['_id']

        response = self.es.update(
            index=INDEX_NAME,
            id=document_id,
            doc_type=DOC_TYPE,
            body={'doc': {'text': 'Updated', 'meta': {'count': 2}}}
        )

        self.assertEqual('updated', response.get('result'))
        self.assertEqual(2, response.get('_version'))

        stored = self.es.get(index=INDEX_NAME, doc_type=DOC_TYPE, id=document_id)
        self.assertEqual('Updated', stored.get('_source').get('text'))
        self.assertEqual(['search', 'mock'], stored.get('_source').get('meta').get('tags'))
        self.assertEqual(2, stored.get('_source').get('meta').get('count'))
        self.assertEqual(BODY.get('author'), stored.get('_source').get('author'))

    def test_should_create_document_with_doc_as_upsert(self):
        response = self.es.update(
            index=INDEX_NAME,
            id=DOC_ID,
            doc_type=DOC_TYPE,
            body={'doc': {'text': 'Upserted'}, 'doc_as_upsert': True}
        )

        self.assertEqual('created', response.get('result'))
        self.assertEqual(1, response.get('_version'))

        stored = self.es.get(index=INDEX_NAME, doc_type=DOC_TYPE, id=DOC_ID)
        self.assertEqual('Upserted', stored.get('_source').get('text'))

    def test_should_create_document_with_upsert_only(self):
        response = self.es.update(
            index=INDEX_NAME,
            id='new-id',
            doc_type=DOC_TYPE,
            body={'upsert': {'counter': 0}}
        )

        self.assertEqual('created', response.get('result'))

        stored = self.es.get(index=INDEX_NAME, doc_type=DOC_TYPE, id='new-id')
        self.assertEqual(0, stored.get('_source').get('counter'))

    def test_should_raise_not_found_when_document_missing(self):
        with self.assertRaises(NotFoundError):
            self.es.update(
                index=INDEX_NAME,
                id='missing-id',
                doc_type=DOC_TYPE,
                body={'doc': {'text': 'Updated'}}
            )

    def test_should_return_not_found_when_ignore_404(self):
        response = self.es.update(
            index=INDEX_NAME,
            id='ignored-id',
            doc_type=DOC_TYPE,
            body={'doc': {'text': 'Updated'}},
            params={'ignore': 404}
        )

        self.assertEqual('not_found', response.get('result'))
        self.assertEqual('ignored-id', response.get('_id'))
