"""
Tests that built-in shape types are emitted correctly.
"""

import os.path
import re
import sys
from pathlib import Path

import pytest

sys.path.append(os.path.join(os.path.dirname(__file__), "../../../tests"))
from gvtest import dot  # pylint: disable=wrong-import-position

shapes = [
    "box",
    "polygon",
    "ellipse",
    "oval",
    "circle",
    "point",
    "egg",
    "triangle",
    "none",
    "plaintext",
    "plain",
    "diamond",
    "trapezium",
    "parallelogram",
    "house",
    "pentagon",
    "hexagon",
    "septagon",
    "octagon",
    "note",
    "tab",
    "folder",
    "box3d",
    "component",
    "cylinder",
    "rect",
    "rectangle",
    "square",
    "star",
    "doublecircle",
    "doubleoctagon",
    "tripleoctagon",
    "invtriangle",
    "invtrapezium",
    "invhouse",
    "underline",
    "Mdiamond",
    "Msquare",
    "Mcircle",
    # biological circuit shapes
    # gene expression symbols
    "promoter",
    "cds",
    "terminator",
    "utr",
    "insulator",
    "ribosite",
    "rnastab",
    "proteasesite",
    "proteinstab",
    # dna construction symbols
    "primersite",
    "restrictionsite",
    "fivepoverhang",
    "threepoverhang",
    "noverhang",
    "assembly",
    "signature",
    "rpromoter",
    "larrow",
    "rarrow",
    "lpromoter",
]

output_types = ["gv", "svg", "xdot"]


def generate_shape_graph(shape, output_type) -> str:
    """
    Produce a graph of the given shape and output format.

    Returns:
        A graph in the given output format.
    """

    input_graph = f'graph G {{ a [label="" shape={shape}] }}'
    output = dot(output_type, source=input_graph)

    if output_type == "svg":
        # Remove the number in "Generated by graphviz version <number>"
        # to able to compare the output to the reference. This version
        # number is different for every Graphviz compilation.
        output = re.sub(
            r"<!-- Generated by graphviz version .*$",
            "<!-- Generated by graphviz version",
            output,
            flags=re.MULTILINE,
        )

    return output


@pytest.mark.parametrize(
    "shape,output_type",
    [(shape, output_type) for shape in shapes for output_type in output_types],
)
def test_shape(shape, output_type):
    """
    Check a shape corresponds to its reference.
    """
    my_dir = Path(__file__).resolve().parent
    output = generate_shape_graph(shape, output_type)

    ref = my_dir / f"reference/{shape}.{output_type}"
    reference = ref.read_text(encoding="utf-8")

    assert reference == output
