# -*- coding: utf-8 -*-
#
# MIT License
# Copyright (c) 2020 Netcloud AG

"""AciClient Testing

"""
from requests import RequestException

from aciClient.aci import ACI
import pytest
import time

__BASE_URL = 'testing-apic.ncdev.ch'


def test_login_ok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'asdafa'}}}
    ]})
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    assert aci.login()


def test_token_ok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    token = aci.getToken()
    assert token == 'tokenxyz'


def test_login_401(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'status_code': 401, 'text': 'not allowed'},
                       status_code=401)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    assert not aci.login()


def test_login_404_exception(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'status_code': 404, 'text': 'Not Found'},
                       status_code=404)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    with pytest.raises(RequestException):
        resp = aci.login()

def test_login_refresh_ok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'refreshTimeoutSeconds': '31', 'token':'tokenxyz'}}}
    ]})
    requests_mock.post(f'https://{__BASE_URL}/api/aaaRefresh.json', json={
        'imdata': [
            {
            'aaaLogin': {
                'attributes': {
                    'refreshTimeoutSeconds': '300',
                    'token':'tokenabc'
                    }
                }
            }
        ]})
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogout.json', json={'imdata': []}, status_code=200)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown', refresh=True)
    aci.login()
    token = aci.getToken()
    time.sleep(2)
    aci.logout()
    assert token != aci.getToken()

def test_login_refresh_nok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'refreshTimeoutSeconds': '31', 'token':'tokenxyz'}}}
    ]})
    requests_mock.post(f'https://{__BASE_URL}/api/aaaRefresh.json', json={
        'imdata': []}, status_code=403)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown', refresh=True)
    aci.login()
    time.sleep(3)
    token = aci.getToken()
    assert not token

def test_renew_cookie_ok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.post(f'https://{__BASE_URL}/api/aaaRefresh.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]},
                       status_code=200)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    assert aci.renewCookie()


def test_renew_cookie_exception(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.post(f'https://{__BASE_URL}/api/aaaRefresh.json', json={'status_code': 401, 'text': 'Not Allowed'},
                       status_code=401)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    with pytest.raises(RequestException):
        aci.renewCookie()


def test_get_tenant_ok(requests_mock):
    uri = 'mo/uni/tn-common.json'
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.get(f'https://{__BASE_URL}/api/{uri}',
                      json={'imdata': [{'fvTenant': {'attributes':
                                                         {'annotation': '',
                                                          'childAction': '',
                                                          'descr': '',
                                                          'dn': 'uni/tn-common',
                                                          'extMngdBy': '',
                                                          'lcOwn': 'local',
                                                          'modTs': '2020-11-23T15:53:52.014+00:00',
                                                          'monPolDn': 'uni/tn-common/monepg-default',
                                                          'name': 'common',
                                                          'nameAlias': '',
                                                          'ownerKey': '',
                                                          'ownerTag': '',
                                                          'status': '',
                                                          'uid': '0'}}}]
                            })
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.getJson(uri)
    assert 'fvTenant' in resp[0]


def test_get_tenant_ok(requests_mock):
    uri = 'mo/uni/tn-common.json'
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.get(f'https://{__BASE_URL}/api/{uri}',
                      json={'imdata': [{'fvTenant': {'attributes':
                                                         {'annotation': '',
                                                          'childAction': '',
                                                          'descr': '',
                                                          'dn': 'uni/tn-common',
                                                          'extMngdBy': '',
                                                          'lcOwn': 'local',
                                                          'modTs': '2020-11-23T15:53:52.014+00:00',
                                                          'monPolDn': 'uni/tn-common/monepg-default',
                                                          'name': 'common',
                                                          'nameAlias': '',
                                                          'ownerKey': '',
                                                          'ownerTag': '',
                                                          'status': '',
                                                          'uid': '0'}}}]
                            })
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.getJson(uri)
    assert 'fvTenant' in resp[0]


def test_get_tenant_not_found(requests_mock):
    uri = 'mo/uni/tn-commmmmon.json'
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.get(f'https://{__BASE_URL}/api/{uri}',
                      json={'error': 'Not found'}, status_code=404)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.getJson(uri)
    assert 'error' in resp


def test_post_tenant_ok(requests_mock):
    post_data = {'fvTenant': {'attributes':
                                  {'descr': '',
                                   'dn': 'uni/tn-test',
                                   'status': 'modified,created'}}
                 }
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.post(f'https://{__BASE_URL}/api/mo.json',
                       json={'imdata': post_data})
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.postJson(post_data)
    assert resp == 200


def test_post_tenant_bad_request(requests_mock):
    post_data = {'fvTenFailFailant': {'attributes':
                                          {'descr': '',
                                           'dn': 'uni/tn-test',
                                           'status': 'modified,created'}}
                 }
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.post(f'https://{__BASE_URL}/api/mo.json',
                       json={'imdata': [
                           {'error': {'attributes': {'text': 'tokenxyz'}}}]},
                       status_code=400)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.postJson(post_data)
    assert resp.startswith('400: ')


def test_post_tenant_forbidden_exception(requests_mock):
    post_data = {'fvTenFailFailant': {'attributes':
                                          {'descr': '',
                                           'dn': 'uni/tn-test',
                                           'status': 'modified,created'}}
                 }
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})
    requests_mock.post(f'https://{__BASE_URL}/api/mo.json',
                       json={'imdata': [
                           {'error': {'attributes': {'text': 'tokenxyz'}}}]},
                       status_code=403)
    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    with pytest.raises(RequestException):
        aci.postJson(post_data)


def test_snapshot_ok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/mo.json', json={"totalCount": "0", "imdata": []})
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})

    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.snapshot(description='unit_test')
    assert resp


def test_snapshot_nok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/mo.json',
                       json={"totalCount": "0", "imdata": [{"error": {"attributes": {"text": "Error UnitTest"}}}]},
                       status_code=400)
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})

    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.snapshot(description='unit_test')
    assert not resp

def test_snapshot_tenant_ok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/mo.json', json={"totalCount": "0", "imdata": []})
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})

    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.snapshot(description='unit_test', target_dn='/uni/tn-test')
    assert resp


def test_snapshot_tenant_nok(requests_mock):
    requests_mock.post(f'https://{__BASE_URL}/api/mo.json',
                       json={"totalCount": "0", "imdata": [{"error": {"attributes": {"text": "Error UnitTest"}}}]},
                       status_code=400)
    requests_mock.post(f'https://{__BASE_URL}/api/aaaLogin.json', json={'imdata': [
        {'aaaLogin': {'attributes': {'token': 'tokenxyz'}}}
    ]})

    aci = ACI(apicIp=__BASE_URL, apicUser='admin', apicPasword='unkown')
    aci.login()
    resp = aci.snapshot(description='unit_test', target_dn='/uni/tn-test')
    assert not resp
