import re


def extract_node_attrs(node_declaration):
    """Returns three specific attributes of a FASTG node declaration.

        As an example, extract_node_attrs("EDGE_3_length_100_cov_28.087'")
        should return {"name": "3-", "length": 100, "cov": 28.087}.

        Parameters
        ----------

        node_declaration: str
            A string tentatively representing a FASTG node declaration (even
            though it should start with ">EDGE"). We impose some pretty strict
            criteria on how this declaration can be structured in order to make
            sure that we get the same amount of information from all nodes in
            the assembly graph file.

        Returns
        -------

        dict
            A mapping of "name", "length", and "cov" to the corresponding
            corresponding node attributes. The "name" value should be a str,
            the "length" value should be an int, the "cov" value should be a
            float, and the "rc" value should be a bool.

        Raises
        ------

        If the regular expression we use to retrieve information from a node
        declaration does not match the node_declaration, this will raise a
        ValueError.
    """
    rc = False
    if node_declaration.endswith("'"):
        rc = True
        node_declaration = node_declaration[0:-1]
    p = re.compile(
        r"EDGE_(?P<node>[a-zA-Z\d]+?)_length_(?P<length>\d+?)_cov_(?P<cov>[\d|\.]+)"  # noqa
    )
    m = p.search(node_declaration)
    if m is None:
        raise ValueError(
            'Wasn\'t able to find all info in the node declaration "{}". '
            "This assembly graph is likely formatted in a way that pyfastg "
            "does not support."
        )
    name = m.group("node")
    if rc:
        name += "-"
    else:
        name += "+"
    return {
        "name": name,
        "length": int(m.group("length")),
        "cov": float(m.group("cov")),
    }