import collections
import json
import subprocess

import pytest
from pr2test.marks import require_root

from pyroute2 import NDB
from pyroute2.common import dqn2int, hexdump, hexload
from pyroute2.dhcp import client

pytestmark = [require_root()]


@pytest.fixture
def ctx():
    ndb = NDB()
    index = 0
    ifname = ''
    # get a DHCP default route, if exists
    with ndb.routes.dump() as dump:
        dump.select_records(proto=16, dst='')
        for route in dump:
            index = route.oif
            ifname = ndb.interfaces[index]['ifname']
            break
        yield collections.namedtuple('Context', ['ndb', 'index', 'ifname'])(
            ndb, index, ifname
        )
    ndb.close()


def _do_test_client_module(ctx):
    if ctx.index == 0:
        pytest.skip('no DHCP interfaces detected')

    response = client.action(ctx.ifname)
    options = response['options']
    router = response['options']['router'][0]
    prefixlen = dqn2int(response['options']['subnet_mask'])
    address = response['yiaddr']
    l2addr = response['chaddr']

    # convert addresses like 96:0:1:45:fa:6c into 96:00:01:45:fa:6c
    assert (
        hexdump(hexload(l2addr)) == ctx.ndb.interfaces[ctx.ifname]['address']
    )
    assert router == ctx.ndb.routes['default']['gateway']
    assert options['lease_time'] > 0
    assert prefixlen > 0
    assert address is not None
    return response


def test_client_module(ctx):
    _do_test_client_module(ctx)


def test_client_console(ctx):
    response_from_module = json.loads(json.dumps(_do_test_client_module(ctx)))
    client = subprocess.run(
        ['pyroute2-dhcp-client', ctx.ifname], stdout=subprocess.PIPE
    )
    response_from_console = json.loads(client.stdout)
    assert response_from_module == response_from_console
