"""
B-ASIC test suite for Inputport
"""

import pytest

from b_asic import InputPort, OutputPort
from b_asic import Signal

@pytest.fixture
def inp_port():
    return InputPort(None, 0)

@pytest.fixture
def out_port():
    return OutputPort(None, 0)

@pytest.fixture
def out_port2():
    return OutputPort(None, 1)

@pytest.fixture
def dangling_sig():
    return Signal()

@pytest.fixture
def s_w_source(out_port):
    return Signal(source=out_port)

@pytest.fixture
def sig_with_dest(inp_port):
    return Signal(destination=inp_port)

@pytest.fixture
def connected_sig(inp_port, out_port):
    return Signal(source=out_port, destination=inp_port)

def test_connect_then_disconnect(inp_port, out_port):
    """Test connect unused port to port."""
    s1 = inp_port.connect(out_port)

    assert inp_port.connected_source == out_port
    assert inp_port.signals == [s1]
    assert out_port.signals == [s1]
    assert s1.source is out_port
    assert s1.destination is inp_port

    inp_port.remove_signal(s1)

    assert inp_port.connected_source is None
    assert inp_port.signals == []
    assert out_port.signals == [s1]
    assert s1.source is out_port
    assert s1.destination is None

def test_connect_used_port_to_new_port(inp_port, out_port, out_port2):
    """Does connecting multiple ports to an inputport throw error?"""
    inp_port.connect(out_port)
    with pytest.raises(Exception):
        inp_port.connect(out_port2)

def test_add_signal_then_disconnect(inp_port, s_w_source):
    """Can signal be connected then disconnected properly?"""
    inp_port.add_signal(s_w_source)

    assert inp_port.connected_source == s_w_source.source
    assert inp_port.signals == [s_w_source]
    assert s_w_source.source.signals == [s_w_source]
    assert s_w_source.destination is inp_port

    inp_port.remove_signal(s_w_source)

    assert inp_port.connected_source is None
    assert inp_port.signals == []
    assert s_w_source.source.signals == [s_w_source]
    assert s_w_source.destination is None

def test_set_value_length_pos_int(inp_port):
    inp_port.value_length = 10
    assert inp_port.value_length == 10

def test_set_value_length_zero(inp_port):
    inp_port.value_length = 0
    assert inp_port.value_length == 0

def test_set_value_length_neg_int(inp_port):
    with pytest.raises(Exception):
        inp_port.value_length = -10

def test_set_value_length_complex(inp_port):
    with pytest.raises(Exception):
        inp_port.value_length = (2+4j)

def test_set_value_length_float(inp_port):
    with pytest.raises(Exception):
        inp_port.value_length = 3.2

def test_set_value_length_pos_then_none(inp_port):
    inp_port.value_length = 10
    inp_port.value_length = None
    assert inp_port.value_length is None