import textwrap


def construct_using_clause(metarels, join_hint, index_hint):
    """
    Create a Cypher query clause that gives the planner hints to speed up the query

    Parameters
    ----------
    metarels : a metarels or MetaPath object
        the metapath to create the clause for
    join_hint : 'midpoint', bool, or int
        whether to add a join hint to tell neo4j to traverse form both ends of
        the path and join at a specific index. `'midpoint'` or `True` specifies
        joining at the middle node in the path (rounded down if an even number
        of nodes). `False` specifies not to add a join hint. An int specifies
        the node to join on.
    index_hint : bool
        whether to add index hints which specifies the properties of the source
        and target nodes to use for lookup. Enabling both `index_hint` and
        `join_hint` can cause the query to fail.
    """
    using_query = ""
    # Specify index hint for node lookup
    if index_hint:
        using_query = (
            "\n"
            + textwrap.dedent(
                """\
        USING INDEX n0:{source_label}({property})
        USING INDEX n{length}:{target_label}({property})
        """
            )
            .rstrip()
            .format(
                property=property,
                source_label=metarels[0][0],
                target_label=metarels[-1][1],
                length=len(metarels),
            )
        )

    # Specify join hint with node to join on
    if join_hint is not False:
        if join_hint is True or join_hint == "midpoint":
            join_hint = len(metarels) // 2
        join_hint = int(join_hint)
        assert join_hint >= 0
        assert join_hint <= len(metarels)
        using_query += f"\nUSING JOIN ON n{join_hint}"

    return using_query