from cattle import ApiError
from common_fixtures import *  # NOQA


def test_agent_unique(super_client):
    agents = super_client.list_agent(uri='sim://unique')

    if len(agents) == 0:
        agent = super_client.create_agent(uri='sim://unique')
        agent = super_client.wait_success(agent)
        assert agent.state == 'active'
        agent.deactivate()

    try:
        super_client.create_agent(uri='sim://unique')
        assert False
    except ApiError, e:
        assert e.error.code == 'NotUnique'
        pass


def test_list_sort(super_client, context):
    name = random_str()
    containers = []
    for i in range(2):
        c = context.create_container_no_success(name=name, startOnCreate=False)
        containers.append(c)

    r = super_client.list_container(name=name)
    for i in range(len(r)):
        assert containers[i].id == r[i].id

    r = super_client.list_container(name=name, sort='created', order='desc')
    containers.reverse()
    for i in range(len(r)):
        assert containers[i].id == r[i].id


def test_pagination(context):
    client = context.client
    name = random_str()
    containers = []
    for i in range(4):
        c = client.create_container(imageUuid=context.image_uuid, name=name)
        containers.append(c)

    for c in containers:
        client.wait_success(c)

    r = client.list_container(name=name)

    assert len(r) == 4
    try:
        assert r.pagination.next is None
    except AttributeError:
        pass

    collected = {}
    r = client.list_container(name=name, limit=2)
    assert len(r) == 2
    assert r.pagination.next is not None

    for i in r:
        collected[i.id] = True

    r = r.next()

    assert len(r) == 2
    try:
        assert r.pagination.next is None
    except AttributeError:
        pass

    for i in r:
        collected[i.id] = True

    assert len(collected) == 4


def test_pagination_include(super_client, client, context):
    host = context.host
    name = random_str()
    container_ids = []
    containers = []
    for i in range(5):
        c = client.create_container(imageUuid=context.image_uuid,
                                    name=name,
                                    requestedHostId=host.id)
        c = super_client.reload(c)
        containers.append(c)
        container_ids.append(c.id)

    for c in containers:
        client.wait_success(c)

    assert len(containers[0].instanceHostMaps()) == 1
    assert host.id == containers[0].instanceHostMaps()[0].host().id
    r = super_client.list_container(name=name)

    assert len(r) == 5
    for c in r:
        assert len(c.instanceHostMaps()) == 1
        assert c.instanceHostMaps()[0].hostId == host.id

    collected = {}
    r = super_client.list_container(name=name, include='instanceHostMaps',
                                    limit=2)
    assert len(r) == 2
    for c in r:
        collected[c.id] = True
        assert len(c.instanceHostMaps) == 1
        assert c.instanceHostMaps[0].hostId == host.id

    r = r.next()

    assert len(r) == 2
    for c in r:
        collected[c.id] = True
        assert len(c.instanceHostMaps) == 1
        assert c.instanceHostMaps[0].hostId == host.id

    r = r.next()

    assert len(r) == 1
    for c in r:
        collected[c.id] = True
        assert len(c.instanceHostMaps) == 1
        assert c.instanceHostMaps[0].hostId == host.id

    assert not r.pagination.partial

    maps = []
    for id in container_ids:
        maps.extend(super_client.list_instanceHostMap(hostId=host.id,
                                                      instanceId=id))

    assert len(maps) == 5

    maps_from_include = []
    r = super_client.list_host(include='instanceHostMaps', limit=2)

    while True:
        for h in r:
            if h.id == host.id:
                assert len(h.instanceHostMaps) <= 2
                for m in h.instanceHostMaps:
                    if m.instanceId in container_ids:
                        maps_from_include.append(m)

        try:
            r = r.next()
        except AttributeError:
            break

    assert len(maps) == len(maps_from_include)


def test_include_left_join(super_client, context):
    container = context.create_container_no_success(startOnCreate=False)
    container = context.wait_for_state(container, 'stopped')
    c = super_client.by_id('container', container.id,
                           include='instanceHostMaps')

    assert container.id == c.id


def test_include_left_join_sort(super_client, context):
    client = context.client
    name = random_str()
    containers = []
    for i in range(2):
        c = client.create_container(imageUuid=context.image_uuid, name=name)
        containers.append(c)

    for c in containers:
        client.wait_success(c)

    r = super_client.list_container(name=name, include='instanceHostMaps',
                                    sort='created', order='asc')
    for i in range(len(r)):
        assert containers[i].id == r[i].id

    r = super_client.list_container(name=name, include='instanceHostMaps',
                                    sort='created', order='desc')
    containers.reverse()
    for i in range(len(r)):
        assert containers[i].id == r[i].id


def test_include(super_client, context):
    container = context.create_container(name='include_test')
    container = super_client.reload(container)

    for link_name in ['instanceHostMaps', 'instancehostmaps']: