from pathlib import Path

from websites_test_framework.css_parser import (
    CssSimpleParser,
    CssError,
    looks_like_css_code,
)
from websites_test_framework.custom_types import Property


def read_css(relative_path: str):
    path = (Path(__file__).parent / "samples" / relative_path).resolve()
    return CssSimpleParser(path.read_text("utf8"))


def test_valid_css_file():
    css_structure = read_css("valid.css")
    assert css_structure.has_selector(".profil:nth-child(odd)"), css_structure.selectors
    assert css_structure.has_selector(".profil:hover"), css_structure.selectors
    assert css_structure.has_selector(r'a[href ^= "../"]'), css_structure.selectors
    for header in css_structure.rules_headers:
        assert header.strip() == header
    assert "  @keyframes animcolorlang {" in css_structure.raw.split("\n")
    assert "@keyframes animcolorlang" in css_structure.rules_headers
    assert "@keyframes animcolorlang" not in css_structure.selectors
    assert "@keyframes" in css_structure.at_rules_names


def test_other_valid_css_file():
    css_structure = read_css("other_valid.css")
    assert css_structure.has_selector(":root"), css_structure.selectors
    root_rules = css_structure.find_all(":root")
    assert len(root_rules) == 1
    root_rule = root_rules[0]
    assert root_rule.header == ":root"
    assert css_structure.has_selector(".Q"), css_structure.selectors
    q_rules = css_structure.find_all(".Q")
    assert len(q_rules) == 3


def test_css_with_multiline_comment():
    css_structure = read_css("css_with_multiline_comment.css")
    comment = (
        "\n#questions_conditionnelles>label>input:checked #type_de_pro{\n    display: block;\n}\n"
    )
    assert comment in css_structure.comments


def test_css_parser_comments():
    css_structure = read_css("valid.css")
    assert "animation des photos de A propos" in css_structure.comments


def test_css_with_escaped_quotation_mark():
    css_structure = read_css("css_escaped_quotes.css")
    assert len(css_structure.content) == 1
    rule = css_structure.rules[0]
    assert len(rule.content) == 2
    assert rule.header == "blockquote::before, blockquote::after"
    property_content, property_color = rule.content
    assert isinstance(property_content, Property)
    assert isinstance(property_color, Property)
    assert property_content.name == "content"
    assert property_content.value == '"\\""'
    assert property_color.name == "color"
    assert property_color.value == "turquoise"


def test_image_data():
    css_structure = read_css("image_data_sample.css")
    assert ".black_blend" in css_structure.selectors


# Invalid CSS files: parser must raise an Exception.


def test_invalid_css_file():
    valid = True
    try:
        read_css("invalid.css")
    except CssError:
        valid = False
    assert not valid


def test_no_block_to_close_error():
    valid = True
    try:
        read_css("no_block_to_close.css")
    except CssError:
        valid = False
    assert not valid


def test_looks_like_css_code_extract():
    text1 = "color: red;"
    text2 = "{color: red;}"
    text3 = "{color: red;\n    color:yellow}"
    text4 = "\np {color: red;\n  color:yellow}\n"
    text5 = "\np {color: red;\n  color:yellow\n"
    text6 = "\np {color: red;\n  color:yellow}\n}\n\n }\n"
    not_a_css_extract = "Don't use {color: red;} here."
    just_text = "This is a comment."
    comment_too = "TODO: add something here, remove something there."
    assert looks_like_css_code(text1)
    assert looks_like_css_code(text2)
    assert looks_like_css_code(text3)
    assert looks_like_css_code(text4)
    assert looks_like_css_code(text5)
    assert looks_like_css_code(text6)
    assert not looks_like_css_code(not_a_css_extract)
    assert not looks_like_css_code(just_text)
    assert not looks_like_css_code(comment_too)


if __name__ == "__main__":
    test_looks_like_css_code_extract()
