from typing import Optional

from chemrecon.schema.db_object import Relation, SourceDatabase, InverseRelation, col_src
from chemrecon.schema.entry_types.enzyme import Enzyme
from chemrecon.schema.entry_types.reaction import Reaction


class ReactionHasEnzyme(Relation[Reaction, Enzyme]):
    """ Relates a reaction entry to the given enzyme which catalyses the reaction.
    """
    # Attributes
    src: SourceDatabase  #: The source of the relation

    # Database
    entrytype_name = 'Reaction has Enzyme'
    _table_name = 'ReactionHasEnzyme'
    symmetric = False
    source_entrytype = Reaction
    target_entrytype = Enzyme
    _attribute_columns = [
        col_src
    ]
    _index = [0]

    def __init__(
        self,
        src: SourceDatabase = SourceDatabase.unknown,
        recon_id_1: Optional[int] = None,
        recon_id_2: Optional[int] = None
    ):
        super().__init__(recon_id_1, recon_id_2)
        self.src = src

    def _vis_str(self) -> str:
        return f'catalysed by'

class EnzymeCatalyzesReaction(InverseRelation[Enzyme, Reaction]):
    """ Relates an enzyme entry to a reaction which it catalyses.
    """
    # Attributes
    src: SourceDatabase  #: The source of the relation

    # Inverse
    inverse_main_relation = ReactionHasEnzyme

    # Database
    entrytype_name = 'Enzyme Catalyzes Reaction'
    _table_name = 'EnzymeCatalyzesReaction'
    symmetric = False
    source_entrytype = Enzyme
    target_entrytype = Reaction
    _attribute_columns = [
        col_src
    ]
    _index = [0]

    def __init__(
        self,
        src: SourceDatabase = SourceDatabase.unknown,
        recon_id_1: Optional[int] = None,
        recon_id_2: Optional[int] = None
    ):
        super().__init__(recon_id_1, recon_id_2)
        self.src = src


    def _vis_str(self) -> str:
        return f'catalyses'

# Set inverse
ReactionHasEnzyme.has_inverse = EnzymeCatalyzesReaction
