# -*- coding: utf-8 -*-

"""This module investigates the properties of paths of length two (A - B - C)."""

from typing import Dict, Iterable, List, Mapping, Tuple

from pybel import BELGraph
from pybel.constants import (
    ACTIVITY, CAUSAL_RELATIONS, DEGRADATION, LINE, MODIFIER, RELATION, SOURCE, TARGET, TRANSLOCATION,
)
from pybel.dsl import BaseEntity, ComplexAbundance, NamedComplexAbundance
from pybel.struct.filters import edge_predicate, has_protein_modification, part_has_modifier
from pybel.typing import EdgeData


def self_edge_filter(_: BELGraph, source: BaseEntity, target: BaseEntity, __: str) -> bool:
    """Check if the source and target nodes are the same."""
    return source == target


def has_protein_modification_increases_activity(
    graph: BELGraph,
    source: BaseEntity,
    target: BaseEntity,
    key: str,
) -> bool:
    """Check if pmod of source causes activity of target."""
    edge_data = graph[source][target][key]
    return has_protein_modification(graph, source) and part_has_modifier(edge_data, TARGET, ACTIVITY)


@edge_predicate
def has_degradation_increases_activity(edge_data: EdgeData) -> bool:
    """Check if the degradation of source causes activity of target."""
    return part_has_modifier(edge_data, SOURCE, DEGRADATION) and part_has_modifier(edge_data, TARGET, ACTIVITY)


@edge_predicate
def has_translocation_increases_activity(edge_data: EdgeData) -> bool:
    """Check if the translocation of source causes activity of target."""
    return part_has_modifier(edge_data, SOURCE, TRANSLOCATION) and part_has_modifier(edge_data, TARGET, ACTIVITY)


def complex_has_member(graph: BELGraph, complex_node: ComplexAbundance, member_node: BaseEntity) -> bool:
    """Check if the given complex contains the member."""
    return member_node in complex_node.members


def complex_increases_activity(graph: BELGraph, u: BaseEntity, v: BaseEntity, key: str) -> bool:
    """Return if the formation of a complex with u increases the activity of v."""
    return (
        isinstance(u, (ComplexAbundance, NamedComplexAbundance)) and
        complex_has_member(graph, u, v) and
        part_has_modifier(graph[u][v][key], TARGET, ACTIVITY)