from datafinder.typed_attributes import *
from datafinder import QueryRunnerBase, DataFrame
{% for rpm in rcm.property_mappings %}
{% if not is_primitive(rpm.property) %}from {{rpm.property.name.lower()}}_finder import {{rpm.property.type.name}}RelatedFinder
{% endif %}
{% endfor %}


class {{rcm.clazz.name}}Finder:
    __table = '{{rcm.property_mappings[0].target.table.name}}'

{% for rpm in rcm.property_mappings %}
{% if is_primitive(rpm.property) %}
    __{{rpm.property.name}} = {{rpm.property.type.name}}Attribute('{{rpm.target.name}}', '{{rpm.target.type}}', '{{rpm.target.table.name}}')
{% endif %}
{% endfor %}
{% for rpm in rcm.property_mappings %}
{% if not is_primitive(rpm.property) %}
    __{{rpm.property.name}} = {{rpm.property.type.name}}RelatedFinder(Attribute('{{rpm.target.lhs.name}}', '{{rpm.target.lhs.type}}', '{{rpm.target.lhs.table.name}}'),Attribute('{{rpm.target.rhs.name}}', '{{rpm.target.rhs.type}}', '{{rpm.target.rhs.table.name}}'))
{% endif %}
{% endfor %}

{% for rpm in rcm.property_mappings %}
{% if is_primitive(rpm.property) %}
    @staticmethod
    def {{rpm.property.name}}() -> {{rpm.property.type.name}}Attribute:
        return {{rcm.clazz.name}}Finder.__{{rpm.property.name}}

{% else %}
    @staticmethod
    def {{rpm.property.name}}() -> {{rpm.property.type.name}}RelatedFinder:
        return {{rcm.clazz.name}}Finder.__{{rpm.property.name}}

{% endif %}
{% endfor %}
    @staticmethod
    def find_all(date_from: datetime.date, date_to: datetime.date, as_of: str,
                 display_columns: list[Attribute],
                 filter_op: Operation = NoOperation()) -> DataFrame:
        return QueryRunnerBase.get_runner().select(display_columns, {{rcm.clazz.name}}Finder.__table, filter_op)


class {{rcm.clazz.name}}RelatedFinder:
    def __init__(self, source: Attribute, target: Attribute):
        join = JoinOperation(source,target)
{% for rpm in rcm.property_mappings %}
{% if is_primitive(rpm.property) %}
        self.__{{rpm.property.name}} = {{rpm.property.type.name}}Attribute('{{rpm.target.name}}', '{{rpm.target.type}}', '{{rpm.target.table.name}}', join)
{% endif %}
{% endfor %}
{% for rpm in rcm.property_mappings %}
{% if not is_primitive(rpm.property) %}
        self.__{{rpm.property.name}} = {{rpm.property.type.name}}RelatedFinder(Attribute('{{rpm.target.lhs.name}}', '{{rpm.target.lhs.type}}', '{{rpm.target.lhs.table.name}}'),Attribute('{{rpm.target.rhs.name}}', '{{rpm.target.rhs.type}}', '{{rpm.target.rhs.table.name}}'))
{% endif %}
{% endfor %}

{% for rpm in rcm.property_mappings %}
{% if is_primitive(rpm.property) %}
    def {{rpm.property.name}}(self) -> {{rpm.property.type.name}}Attribute:
        return self.__{{rpm.property.name}}

{% else %}
    def {{rpm.property.name}}(self) -> {{rpm.property.type.name}}RelatedFinder:
        return self.__{{rpm.property.name}}

{% endif %}
{% endfor %}
