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


@pytest.mark.parametrize(
    "constant,value",
    [(c.BLACK, 0),
     (c.MIN_COLOR, 0),
     (c.MIN_STANDARD_COLOR, 0),
     (c.RED, 1),
     (c.GREEN, 2),
     (c.YELLOW, 3),
     (c.BLUE, 4),
     (c.MAGENTA, 5),
     (c.CYAN, 6),
     (c.WHITE, 7),
     (c.BRIGHT_BLACK, 8),
     (c.BRIGHT_RED, 9),
     (c.BRIGHT_GREEN, 10),
     (c.BRIGHT_YELLOW, 11),
     (c.BRIGHT_BLUE, 12),
     (c.BRIGHT_MAGENTA, 13),
     (c.BRIGHT_CYAN, 14),
     (c.BRIGHT_WHITE, 15),
     (c.MAX_COLOR, 255),
     (c.MAX_STANDARD_COLOR, 15),
     (c.GRAY0, 232),
     (c.MIN_GRAY_COLOR, 232),
     (c.GRAY1, 233),
     (c.GRAY2, 234),
     (c.GRAY3, 235),
     (c.GRAY4, 236),
     (c.GRAY5, 237),
     (c.GRAY6, 238),
     (c.GRAY7, 239),
     (c.GRAY8, 240),
     (c.GRAY9, 241),
     (c.GRAY10, 242),
     (c.GRAY11, 243),
     (c.GRAY12, 244),
     (c.GRAY13, 245),
     (c.GRAY14, 246),
     (c.GRAY15, 247),
     (c.GRAY16, 248),
     (c.GRAY17, 249),
     (c.GRAY18, 250),
     (c.GRAY19, 251),
     (c.GRAY20, 252),
     (c.GRAY21, 253),
     (c.GRAY22, 254),
     (c.GRAY23, 255),
     (c.MAX_GRAY_COLOR, 255),
     (c.MIN_ENHANCED_COLOR, 16),
     (c.MAX_ENHANCED_COLOR, 231)])
def test_color_name_indexes(constant, value):
    fg_cd = CSI + "38;5;" + str(value) + "m"
    bg_cd = CSI + "48;5;" + str(value) + "m"
    assert constant == value
    assert c.color_code(value) == fg_cd
    assert c.color_code(None, value) == bg_cd
    assert c.color_code(value, value) == fg_cd + bg_cd


####################################################################################################
# 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_GRAY_COLOR + 1)])
def test_color_code_invalid_foreground(value):
    expected_msg_contains = "Foreground 256 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_GRAY_COLOR + 1)])
def test_color_code_invalid_background(value):
    expected_msg_contains = "Background 256 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
