import json

import httpretty
import pytest

import pypuppetdb


def stub_request(url, data=None, method=httpretty.GET, status=200, **kwargs):
    if data is None:
        body = '[]'
    else:
        with open(data, 'r') as d:
            body = json.load(d.read())
    return httpretty.register_uri(method, url, body=body, status=status,
                                  **kwargs)


@pytest.fixture(params=['string', 'QueryBuilder'])
def query(request):
    key = 'certname'
    value = 'node1'
    if request.param == 'string':
        return '["{0}", "=", "{1}"]'.format(key, value)
    elif request.param == 'QueryBuilder':
        return pypuppetdb.QueryBuilder.EqualsOperator(key, value)


class TestQueryAPI(object):

    def test_facts(self, api):
        facts_body = [{
            'certname': 'test_certname',
            'name': 'test_name',
            'value': 'test_value',
            'environment': 'test_environment',
        }]
        facts_url = 'http://localhost:8080/pdb/query/v4/facts'

        httpretty.enable()
        httpretty.register_uri(httpretty.GET, facts_url,
                               body=json.dumps(facts_body))

        for fact in api.facts():
            pass

        assert httpretty.last_request().path == '/pdb/query/v4/facts'

        httpretty.disable()
        httpretty.reset()

    def test_fact_names(self, api):
        httpretty.enable()
        stub_request('http://localhost:8080/pdb/query/v4/fact-names')
        api.fact_names()
        assert httpretty.last_request().path == '/pdb/query/v4/fact-names'
        httpretty.disable()
        httpretty.reset()

    def test_normalize_resource_type(self, api):
        assert api._normalize_resource_type('sysctl::value') == \
               'Sysctl::Value'
        assert api._normalize_resource_type('user') == 'User'

    def test_environments(self, api):
        httpretty.enable()
        stub_request('http://localhost:8080/pdb/query/v4/environments')
        api.environments()
        assert httpretty.last_request().path == '/pdb/query/v4/environments'
        httpretty.disable()
        httpretty.reset()

    def test_inventory(self, api):
        inventory_body = [{
            'certname': 'test_certname',
            'timestamp': '2017-06-05T20:18:23.374Z',
            'environment': 'test_environment',
            'facts': 'test_facts',
            'trusted': 'test_trusted'
        }]
        inventory_url = 'http://localhost:8080/pdb/query/v4/inventory'

        httpretty.enable()
        httpretty.register_uri(httpretty.GET, inventory_url,
                               body=json.dumps(inventory_body))
        for inv in api.inventory():
            pass

        assert httpretty.last_request().path == '/pdb/query/v4/inventory'

        httpretty.disable()
        httpretty.reset()

    def test_nodes_single(self, api):
        body = {
            "cached_catalog_status": "not_used",
            "catalog_environment": "production",
            "catalog_timestamp": "2016-08-15T11:06:26.275Z",
            "certname": "greenserver.vm",
            "deactivated": None,
            "expired": None,
            "facts_environment": "production",
            "facts_timestamp": "2016-08-15T11:06:26.140Z",
            "latest_report_hash": "4a956674b016d95a7b77c99513ba26e4a744f8d1",
            "latest_report_noop": False,
            "latest_report_noop_pending": None,
            "latest_report_status": "changed",
            "report_environment": "production",
            "report_timestamp": "2016-08-15T11:06:18.393Z"
        }
        url = 'http://localhost:8080/pdb/query/v4/nodes'

        httpretty.enable()
        httpretty.register_uri(httpretty.GET, url,
                               body=json.dumps(body))

        nodes = list(api.nodes(query='["=","certname","greenserver.vm"'))

        assert len(nodes) == 1
        assert nodes[0].name == "greenserver.vm"

        assert httpretty.last_request().path.startswith('/pdb/query/v4/nodes')

        httpretty.disable()
        httpretty.reset()
