import pytest
from easyansi import colors as c
from easyansi._core.codes import CSI


####################################################################################################
# color, color_code
####################################################################################################


def test_color_code_no_selection():
    expected_msg = "Must provide either a foreground or background color index"
    with pytest.raises(ValueError) as vl_error:
        c.color_code(None, None)
    assert expected_msg == str(vl_error.value)


@pytest.mark.parametrize(
    "value",
    [(c.MIN_COLOR - 1),
     (c.MAX_COLOR + 1),
     (c.MIN_STANDARD_COLOR - 1),
     (c.MAX_STANDARD_COLOR + 1)])
def test_color_code_invalid_foreground(value):
    expected_msg_contains = "Foreground Color Index"
    with pytest.raises(ValueError) as vl_error:
        c.color_code(value, None)
    assert expected_msg_contains in str(vl_error.value)


@pytest.mark.parametrize(
    "value",
    [(c.MIN_COLOR - 1),
     (c.MAX_COLOR + 1),
     (c.MIN_STANDARD_COLOR - 1),
     (c.MAX_STANDARD_COLOR + 1)])
def test_color_code_invalid_background(value):
    expected_msg_contains = "Background Color Index"
    with pytest.raises(ValueError) as vl_error:
        c.color_code(None, value)
    assert expected_msg_contains in str(vl_error.value)


def test_color_and_color_code_foreground(capsys):
    actual_code = c.color_code(3)
    c.color(3)
    captured = capsys.readouterr()
    assert actual_code == captured.out


def test_color_and_color_code_background(capsys):
    actual_code = c.color_code(None, 4)
    c.color(None, 4)
    captured = capsys.readouterr()
    assert actual_code == captured.out


def test_color_and_color_code_foreground_and_background(capsys):
    actual_code = c.color_code(1, 2)
    c.color(1, 2)
    captured = capsys.readouterr()
    assert actual_code == captured.out


@pytest.mark.parametrize(
    "constant,value,fg_code,bg_code",
    [(c.BLACK, 0, "30", "40"),
     (c.MIN_COLOR, 0, "30", "40"),
     (c.MIN_STANDARD_COLOR, 0, "30", "40"),
     (c.RED, 1, "31", "41"),
     (c.GREEN, 2, "32", "42"),
     (c.YELLOW, 3, "33", "43"),
     (c.BLUE, 4, "34", "44"),
     (c.MAGENTA, 5, "35", "45"),
     (c.CYAN, 6, "36", "46"),
     (c.WHITE, 7, "37", "47"),
     (c.BRIGHT_BLACK, 8, "90", "100"),
     (c.BRIGHT_RED, 9, "91", "101"),
     (c.BRIGHT_GREEN, 10, "92", "102"),
     (c.BRIGHT_YELLOW, 11, "93", "103"),
     (c.BRIGHT_BLUE, 12, "94", "104"),
     (c.BRIGHT_MAGENTA, 13, "95", "105"),
     (c.BRIGHT_CYAN, 14, "96", "106"),
     (c.BRIGHT_WHITE, 15, "97", "107"),
     (c.MAX_COLOR, 15, "97", "107"),
     (c.MAX_STANDARD_COLOR, 15, "97", "107")])
def test_actual_color_values(constant, value, fg_code, bg_code):
    fg_cd = CSI + fg_code + "m"
    bg_cd = CSI + bg_code + "m"
    fgbg_cd = CSI + fg_code + ";" + bg_code + "m"
    assert constant == value
    assert c.color_code(value, None) == fg_cd
    assert c.color_code(None, value) == bg_cd
    assert c.color_code(value, value) == fgbg_cd

