import sys

# Purge all relevant modules before loading them
for mod in list(sys.modules):
    if mod.startswith("pysnmp.hlapi.") or mod.startswith("pysnmp_sync_adapter"):
        del sys.modules[mod]

import asyncio
import platform
import os

from pysnmp.hlapi.v3arch.asyncio import *

from pysnmp_sync_adapter import (
    get_cmd_sync, next_cmd_sync, set_cmd_sync, bulk_cmd_sync,
    walk_cmd_sync, bulk_walk_cmd_sync, create_transport
)

if platform.system()=='Windows':
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

community = 'public'
engine = SnmpEngine()
auth_data = CommunityData(community, mpModel=0)


def test_get_cmd_sync():
    err, status, index, binds = get_cmd_sync(
        engine,
        auth_data,
        create_transport(
            UdpTransportTarget, ("demo.pysnmp.com", 161), timeout=2
        ),
        ContextData(),
        ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))
    )
    assert err is None
    assert not status
    assert binds
    assert len(binds) == 1
    assert len(list(binds[0])) == 2
    name, value = binds[0]
    assert name.prettyPrint() == "SNMPv2-MIB::sysDescr.0"
    assert value.prettyPrint() == "#SNMP Agent on .NET Standard"

def test_set_cmd_sync():
    err, status, index, binds = set_cmd_sync(
        engine,
        auth_data,
        create_transport(
            UdpTransportTarget, ("demo.pysnmp.com", 161), timeout=2
        ),
        ContextData(),
        ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))
    )
    assert err is None
    assert str(status) == 'noSuchName'
    assert binds
    assert len(binds) == 1
    assert len(list(binds[0])) == 2
    name, value = binds[0]
    assert name.prettyPrint() == "SNMPv2-MIB::sysDescr.0"
    assert value.prettyPrint() == 'No Such Object currently exists at this OID'

def test_next_cmd_sync():
    err, status, index, binds = next_cmd_sync(
        engine,
        auth_data,
        create_transport(
            UdpTransportTarget, ("demo.pysnmp.com", 161), timeout=2
        ),
        ContextData(),
        ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))
    )
    assert err is None
    assert str(status) == 'noError'
    assert binds
    assert len(binds) == 1
    assert len(list(binds[0])) == 2
    name, value = binds[0]
    assert name.prettyPrint() == "SNMPv2-MIB::sysObjectID.0"
    assert value.prettyPrint() == "SNMPv2-SMI::internet"

def test_bulk_cmd_sync():
    err, status, index, binds = bulk_cmd_sync(
        engine,
        CommunityData(community),
        create_transport(
            UdpTransportTarget, ("demo.pysnmp.com", 161), timeout=2
        ),
        ContextData(),
        0, 2,
        ObjectType(ObjectIdentity('SNMPv2-MIB', 'system'))
    )
    assert err is None
    assert str(status) == 'noError'
    assert binds
    assert len(binds) == 2
    assert len(list(binds[0])) == 2
    assert len(list(binds[1])) == 2
    name, value = binds[0]
    assert name.prettyPrint() == "SNMPv2-MIB::sysDescr.0"
    assert value.prettyPrint() == "#SNMP Agent on .NET Standard"
    name, value = binds[1]
    assert name.prettyPrint() == "SNMPv2-MIB::sysObjectID.0"
    assert value.prettyPrint() == "SNMPv2-SMI::internet"

def test_walk_cmd_sync():
    objects = walk_cmd_sync(
        engine,
        auth_data,
        create_transport(
            UdpTransportTarget, ("demo.pysnmp.com", 161), timeout=2
        ),
        ContextData(),
        ObjectType(ObjectIdentity('SNMPv2-MIB', 'system')),
        timeout=30
    )
    assert len(objects) == 69
    err, status, index, binds = objects[0]
    assert str(status) == 'noError'
    assert binds
    assert len(binds) == 1
    assert len(list(binds[0])) == 2
    name, value = binds[0]
    assert name.prettyPrint() == "SNMPv2-MIB::sysDescr.0"
    assert value.prettyPrint() == "#SNMP Agent on .NET Standard"

def test_bulk_walk_cmd_sync():
    objects = bulk_walk_cmd_sync(
        engine,
        CommunityData(community),
        create_transport(
            UdpTransportTarget, ("demo.pysnmp.com", 161), timeout=2
        ),
        ContextData(),
        0, 25,
        ObjectType(ObjectIdentity('SNMPv2-MIB', 'system')),
        timeout=20
    )
    assert len(objects) == 3
    err, status, index, binds = objects[0]
    assert str(status) == 'noError'
    assert binds
    assert len(binds) == 25
    assert len(list(binds[0])) == 2
    name, value = binds[0]
    assert name.prettyPrint() == "SNMPv2-MIB::sysDescr.0"
    assert value.prettyPrint() == "#SNMP Agent on .NET Standard"
