import json
import pytest
import datetime

from fatcat_openapi_client.rest import ApiException
from fixtures import *


def test_container_coverage(app, mocker):

    # preservation by type histogram
    elastic_resp1 = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {
            'type_preservation': {
              'buckets': [
                {'key': {'release_type': 'article-journal', 'preservation': 'bright'}, 'doc_count': 444},
                {'key': {'release_type': 'book', 'preservation': 'dark'}, 'doc_count': 111},
              ],
              'sum_other_doc_count': 0,
            },
        },
    }

    # preservation by year histogram
    elastic_resp2 = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {
            'year_preservation': {
              'buckets': [
                {'key': {'year': 2004.0, 'preservation': 'bright'}, 'doc_count': 444},
                {'key': {'year': 2005.0, 'preservation': 'dark'}, 'doc_count': 111},
              ],
              'sum_other_doc_count': 0,
            },
        },
    }

    # preservation by volume histogram
    elastic_resp3 = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {
            'volume_preservation': {
              'buckets': [
                {'key': {'volume': "12", 'preservation': 'bright'}, 'doc_count': 444},
                {'key': {'volume': "12", 'preservation': 'dark'}, 'doc_count': 111},
              ],
              'sum_other_doc_count': 0,
            },
        },
    }

    es_raw = mocker.patch('elasticsearch.connection.Urllib3HttpConnection.perform_request')
    es_raw.side_effect = [
        # status
        (200, {}, json.dumps(ES_CONTAINER_STATS_RESP)),
        # type preservation histogram
        (200, {}, json.dumps(elastic_resp1)),
    ]

    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/coverage')
    assert rv.status_code == 200

    es_raw.side_effect = [(200, {}, json.dumps(elastic_resp2))]
    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/preservation_by_year.svg')
    assert rv.status_code == 200

    es_raw.side_effect = [(200, {}, json.dumps(elastic_resp2))]
    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/preservation_by_year.json')
    assert rv.status_code == 200

    es_raw.side_effect = [(200, {}, json.dumps(elastic_resp3))]
    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/preservation_by_volume.svg')
    assert rv.status_code == 200

    es_raw.side_effect = [(200, {}, json.dumps(elastic_resp3))]
    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/preservation_by_volume.json')
    assert rv.status_code == 200


def test_coverage_search(app, mocker):

    # preservation by year histogram
    elastic_resp1 = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {
            'year_preservation': {
              'buckets': [
                {'key': {'year': 2004.0, 'preservation': 'bright'}, 'doc_count': 444},
                {'key': {'year': 2005.0, 'preservation': 'dark'}, 'doc_count': 111},
              ],
              'sum_other_doc_count': 0,
            },
        },
    }

    # preservation by type histogram
    elastic_resp2 = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {
            'type_preservation': {
              'buckets': [
                {'key': {'release_type': 'article-journal', 'preservation': 'bright'}, 'doc_count': 444},
                {'key': {'release_type': 'book', 'preservation': 'dark'}, 'doc_count': 111},
              ],
              'sum_other_doc_count': 0,
            },
        },
    }

    # preservation by date histogram
    today = str(datetime.date.today())
    elastic_resp3 = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {
            'date_preservation': {
              'buckets': [
                {'key': {'date': f'{today}T00:00.000Z', 'preservation': 'bright'}, 'doc_count': 444},
                {'key': {'date': f'{today}T00:00.000Z', 'preservation': 'dark'}, 'doc_count': 111},
              ],
              'sum_other_doc_count': 0,
            },
        },
    }

    es_raw = mocker.patch('elasticsearch.connection.Urllib3HttpConnection.perform_request')
    es_raw.side_effect = [
        # counts summary
        (200, {}, json.dumps(ES_CONTAINER_STATS_RESP)),
        # by type
        (200, {}, json.dumps(elastic_resp2)),
        # by year
        (200, {}, json.dumps(elastic_resp1)),
    ]

    rv = app.get('/coverage/search?q=*')
    assert rv.status_code == 200

    es_raw.side_effect = [
        # counts summary
        (200, {}, json.dumps(ES_CONTAINER_STATS_RESP)),
        # by type
        (200, {}, json.dumps(elastic_resp2)),
        # by date
        (200, {}, json.dumps(elastic_resp3)),
    ]

    rv = app.get('/coverage/search?recent=1&q=*')
    assert rv.status_code == 200


def test_legacy_container_coverage(app, mocker):

    # legacy preservation by year
    elastic_resp1 = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {
            'year_in_ia': {
                'after_key': {'year': 2020.0, 'in_ia': True},
                'buckets': [
                    {'key': {'year': 2004.0, 'in_ia': False}, 'doc_count': 4},
                    {'key': {'year': 2004.0, 'in_ia': True}, 'doc_count': 68},
                    {'key': {'year': 2005.0, 'in_ia': False}, 'doc_count': 26},
                    {'key': {'year': 2005.0, 'in_ia': True}, 'doc_count': 428},
                    {'key': {'year': 2006.0, 'in_ia': False}, 'doc_count': 14},
                    {'key': {'year': 2006.0, 'in_ia': True}, 'doc_count': 487},
                    {'key': {'year': 2007.0, 'in_ia': False}, 'doc_count': 13},
                    {'key': {'year': 2007.0, 'in_ia': True}, 'doc_count': 345},
                ],
            },
        },
    }

    es_raw = mocker.patch('elasticsearch.connection.Urllib3HttpConnection.perform_request')
    es_raw.side_effect = [
        (200, {}, json.dumps(elastic_resp1)),
    ]

    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/ia_coverage_years.json')
    assert rv.status_code == 200

    es_raw.side_effect = [
        (200, {}, json.dumps(elastic_resp1)),
    ]

    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/ia_coverage_years.svg')
    assert rv.status_code == 200


def test_coverage_empty_years(app, mocker):

    elastic_resp = {
        'took': 294,
        'timed_out': False,
        '_shards': {'total': 5, 'successful': 5, 'skipped': 0, 'failed': 0},
        'hits': {'total': 4327, 'max_score': 0.0, 'hits': []},
        'aggregations': {'year_in_ia': {
            'after_key': {'year': 2020.0, 'in_ia': True},
            'buckets': [
            ],
        }},
    }

    es_raw = mocker.patch('elasticsearch.connection.Urllib3HttpConnection.perform_request')
    es_raw.side_effect = [
        (200, {}, json.dumps(elastic_resp)),
    ]

    rv = app.get('/container/aaaaaaaaaaaaaeiraaaaaaaaam/ia_coverage_years.svg')
    assert rv.status_code == 200