""" ChemRecon comes with a set of pre-defined exploration protocols for various purposes.
    These are located in the chemrecon.query.default_protocols module.
    We recommend looking in this file for inspiration on how to define custom protocols.
"""
from src.chemrecon import Direction
from chemrecon.entrygraph.filter import EntryFilterProcedure
from chemrecon.entrygraph.explorationprotocol import ExplorationProtocol
from chemrecon.schema.entry_types.compound import Compound
from chemrecon.schema.entry_types.molstructure_repr import MolStructureRepr
from chemrecon.schema.entry_types.molstructure import MolStructure
from chemrecon.schema.relation_types_composed.compound_has_molstructure_relation import CompoundHasMolStructure
from chemrecon.schema.relation_types_source.compound_reference_relation import CompoundReference
from chemrecon.schema.relation_types_source.molstructure_standardisation_relation import MolStructureStandardization

# TODO filters

# General
# ----------------------------------------------------------------------------------------------------------------------
#: The Compound-Structure protocol can be used to quickly gain an overview of the structural information
#: relating to a given compound.
#: The database compounds are traversed via the `CompoundReference` relation in order to expand the graph to include
#: other databases which contain the compound.
#: The `CompoundHasMolStructure` relation is then used to find the associated structure for each compound.
#: The `MolStructureStandardization` relation is used to standardize various properties of the structures, which can be
#: helpful in case the databases simply disagree on easy-to-standardize properties, such as charge or tautomerism.
protocol_compound_structure = ExplorationProtocol(
    relation_types = {
        (CompoundReference, Direction.SYMMETRIC),
        (CompoundHasMolStructure, Direction.FORWARDS),
        (MolStructureStandardization, Direction.FORWARDS),
    }
)

# Search graphs - for selection rather than manual inspection
# ----------------------------------------------------------------------------------------------------------------------
protocol_select_structure = ExplorationProtocol(
    relation_types = {
        (CompoundReference, Direction.SYMMETRIC),
        (CompoundHasMolStructure, Direction.FORWARDS),
        (MolStructureStandardization, Direction.FORWARDS),
    },
)

# TODO - FILTER - disallow implicit Structures!
def _select_structure_entry_filter(e: MolStructureRepr) -> bool:
    if e.implicit:
        return False
    else:
        return True

struct_repr_filter = EntryFilterProcedure[MolStructureRepr](
    filter_proc = _select_structure_entry_filter
)


# TODO include some ontology relations, such as the old_id and new_id relations

