import pytest

from easyansi import drawing as d
from easyansi import cursor as cur


####################################################################################################
# hline, hline_code
####################################################################################################


def test_hline_invalid_length():
    with pytest.raises(ValueError) as vl_error:
        d.hline(d.MIN_LINE_LENGTH - 1)
    assert "Horizontal Line Length" in str(vl_error.value)


def test_hline_empty_char():
    with pytest.raises(ValueError) as vl_error:
        d.hline(10, char="")
    assert "Horizontal Line Character" in str(vl_error.value)


def test_hline_invalid_style():
    with pytest.raises(ValueError) as vl_error:
        d.hline(10, style="")
    assert "Horizontal Line Style" in str(vl_error.value)


def test_hline_and_hline_code(capsys):
    length = 10
    char = "-="
    actual_code = d.hline_code(length, char=char)
    d.hline(length, char=char)
    captured = capsys.readouterr()
    assert actual_code == captured.out


def test_hline_default_style():
    assert d.hline_code(10) == d.hline_code(10, style=d.styles.SINGLE)


def test_hline_char_overrides_style():
    assert d.hline_code(10, char="=") == d.hline_code(10, char="=", style=d.styles.SINGLE)


@pytest.mark.parametrize(
    "length,char,expected_line",
    [(10, "*", "**********"),
     (11, "@", "@@@@@@@@@@@"),
     (10, "- ", "- - - - - "),
     (11, "- ", "- - - - - -"),
     (11, "<->", "<-><-><-><-")])
def test_hline_valid_char_lines(length, char, expected_line):
    assert expected_line == d.hline_code(length, char=char)


@pytest.mark.parametrize(
    "length,style,expected_line",
    [(10, d.styles.SINGLE, d.single.HORIZONTAL * 10),
     (11, d.styles.SINGLE, d.single.HORIZONTAL * 11),
     (10, d.styles.DOUBLE, d.double.HORIZONTAL * 10),
     (11, d.styles.DOUBLE, d.double.HORIZONTAL * 11),
     (10, d.styles.KEYBOARD, d.keyboard.HORIZONTAL * 10),
     (11, d.styles.KEYBOARD, d.keyboard.HORIZONTAL * 11)])
def test_hline_valid_styles(length, style, expected_line):
    assert expected_line == d.hline_code(length, style=style)


####################################################################################################
# vline, vline_code
####################################################################################################


def test_vline_invalid_length():
    with pytest.raises(ValueError) as vl_error:
        d.vline(d.MIN_LINE_LENGTH - 1)
    assert "Vertical Line Length" in str(vl_error.value)


def test_vline_empty_char():
    with pytest.raises(ValueError) as vl_error:
        d.vline(10, char="")
    assert "Vertical Line Character" in str(vl_error.value)


def test_vline_invalid_style():
    with pytest.raises(ValueError) as vl_error:
        d.vline(10, style="")
    assert "Vertical Line Style" in str(vl_error.value)


def test_vline_and_vline_code(capsys):
    length = 10
    char = "|:"
    actual_code = d.vline_code(length, char=char)
    d.vline(length, char=char)
    captured = capsys.readouterr()
    assert actual_code == captured.out


def test_vline_default_style():
    assert d.vline_code(10) == d.vline_code(10, style=d.styles.SINGLE)


def test_vline_char_overrides_style():
    assert d.vline_code(10, char="=") == d.vline_code(10, char="=", style=d.styles.SINGLE)


@pytest.mark.parametrize(
    "length,char,expected_line",
    [(10, "*", ("*" + cur.down_code() + cur.left_code()) * 9 + "*"),
     (11, "@", ("@" + cur.down_code() + cur.left_code()) * 10 + "@"),
     (10, "| ", ("|" + cur.down_code() + cur.left_code() +
                 " " + cur.down_code() + cur.left_code()) * 4 +
      "|" + cur.down_code() + cur.left_code() + " "),
     (11, "| ", ("|" + cur.down_code() + cur.left_code() +
                 " " + cur.down_code() + cur.left_code()) * 5 + "|"),
     (11, "^|v", ("^" + cur.down_code() + cur.left_code() +
                  "|" + cur.down_code() + cur.left_code() +
                  "v" + cur.down_code() + cur.left_code()) * 3 +
      "^" + cur.down_code() + cur.left_code() + "|")])
def test_vline_valid_char_lines(length, char, expected_line):
    assert expected_line == d.vline_code(length, char=char)


@pytest.mark.parametrize(
    "length,style,expected_line",
    [(10, d.styles.SINGLE, (d.single.VERTICAL + cur.down_code() + cur.left_code()) * 9 + d.single.VERTICAL),
     (11, d.styles.SINGLE, (d.single.VERTICAL + cur.down_code() + cur.left_code()) * 10 + d.single.VERTICAL),
     (10, d.styles.DOUBLE, (d.double.VERTICAL + cur.down_code() + cur.left_code()) * 9 + d.double.VERTICAL),
     (11, d.styles.DOUBLE, (d.double.VERTICAL + cur.down_code() + cur.left_code()) * 10 + d.double.VERTICAL),
     (10, d.styles.KEYBOARD, (d.keyboard.VERTICAL + cur.down_code() + cur.left_code()) * 9 + d.keyboard.VERTICAL),
     (11, d.styles.KEYBOARD, (d.keyboard.VERTICAL + cur.down_code() + cur.left_code()) * 10 + d.keyboard.VERTICAL)])
def test_vline_valid_styles(length, style, expected_line):
    assert expected_line == d.vline_code(length, style=style)


