# Copyright (c) 2015 Ansible, Inc.
# All Rights Reserved

# Python
import pytest
from datetime import datetime
import json

# Django
from django.utils import timezone

# AWX
from awx.main.management.commands.run_fact_cache_receiver import FactBrokerWorker
from awx.main.models.fact import Fact
from awx.main.models.inventory import Host


# TODO: Check that timestamp and other attributes are as expected
def check_process_fact_message_module(fact_returned, data, module_name):
    date_key = data['date_key']

    # Ensure 1, and only 1, fact created
    timestamp = datetime.fromtimestamp(date_key, timezone.utc)
    assert 1 == Fact.objects.all().count()

    host_obj = Host.objects.get(name=data['host'], inventory__id=data['inventory_id'])
    assert host_obj is not None
    fact_known = Fact.get_host_fact(host_obj.id, module_name, timestamp)
    assert fact_known is not None
    assert fact_known == fact_returned

    assert host_obj == fact_returned.host
    if module_name == 'ansible':
        assert data['facts'] == fact_returned.facts
    else:
        assert data['facts'][module_name] == fact_returned.facts
    assert timestamp  == fact_returned.timestamp
    assert module_name == fact_returned.module


@pytest.mark.django_db
def test_process_fact_message_ansible(fact_msg_ansible, monkeypatch_jsonbfield_get_db_prep_save):
    receiver = FactBrokerWorker(None)
    fact_returned = receiver.process_fact_message(fact_msg_ansible, None)
    check_process_fact_message_module(fact_returned, fact_msg_ansible, 'ansible')


@pytest.mark.django_db
def test_process_fact_message_packages(fact_msg_packages, monkeypatch_jsonbfield_get_db_prep_save):
    receiver = FactBrokerWorker(None)
    fact_returned = receiver.process_fact_message(fact_msg_packages, None)
    check_process_fact_message_module(fact_returned, fact_msg_packages, 'packages')


@pytest.mark.django_db
def test_process_fact_message_services(fact_msg_services, monkeypatch_jsonbfield_get_db_prep_save):
    receiver = FactBrokerWorker(None)
    fact_returned = receiver.process_fact_message(fact_msg_services, None)
    check_process_fact_message_module(fact_returned, fact_msg_services, 'services')


@pytest.mark.django_db
def test_process_facts_message_ansible_overwrite(fact_scans, fact_msg_ansible, monkeypatch_jsonbfield_get_db_prep_save):
    '''
    We pickypack our fact sending onto the Ansible fact interface.
    The interface is <hostname, facts>. Where facts is a json blob of all the facts.
    This makes it hard to decipher what facts are new/changed.
    Because of this, we handle the same fact module data being sent multiple times
    and just keep the newest version.
    '''
    #epoch = timezone.now()
    epoch = datetime.fromtimestamp(fact_msg_ansible['date_key'])
    fact_scans(fact_scans=1, timestamp_epoch=epoch)
    key = 'ansible.overwrite'
    value = 'hello world'

    receiver = FactBrokerWorker(None)
    receiver.process_fact_message(fact_msg_ansible, None)

    fact_msg_ansible['facts'][key] = value
    fact_returned = receiver.process_fact_message(fact_msg_ansible, None)

    fact_obj = Fact.objects.get(id=fact_returned.id)
    assert key in fact_obj.facts
    assert fact_msg_ansible['facts'] == (json.loads(fact_obj.facts) if isinstance(fact_obj.facts, unicode) else fact_obj.facts) # TODO: Just make response.data['facts'] when we're only dealing with postgres, or if jsonfields ever fixes this bug
