{% macro render_factory(model) %}
{% set dep = deps[model.name.camel] %}
{% set links = model.links if dep else [] %}


class {{ model.name.camel }}Factory(SQLAlchemyFactory[{{ model.name.db }}]):
    __sync_persistence__ = True
    {% if dep %}
    __set_relationships__ = True
    {% endif %}

    {% for link in links %}
    {% set is_batch = link.t1 == 'many' %}
    {% set name = link.m2.name.snake_plural if is_batch else link.m2.name.snake %}
    {% if link.m2.name.camel in dep %}
    @classmethod
    def {{ name }}(cls):
        {% if is_batch %}
        return [{{ link.m2.name.camel }}Factory.build() for _ in range(10)]
        {% else %}
        return {{ link.m2.name.camel }}Factory.build()
        {% endif %}

    {% else %}
    {% set res = '[]' if is_batch else 'None' %}
    @classmethod
    def {{ name }}(cls):
        return {{ res }}

    {% endif %}
    {% endfor %}
{% endmacro %}

{% macro render_user_factory(model) %}
class UserFactory(SQLAlchemyFactory[DBUser]):
    __sync_persistence__ = True

    scopes = ''

    @staticmethod
    def _username() -> Callable[..., str]:
        flag = -1

        def f(*args, **kwargs):
            nonlocal flag
            flag += 1
            return 'admin' if flag == 0 else f'user{flag}'

        return f

    username = PostGenerated(_username())

    @staticmethod
    def _hashed_password() -> Callable[..., str]:
        flag = -1

        def f(*args, **kwargs):
            nonlocal flag
            flag += 1
            return auth.get_password_hash('admin' if flag == 0 else f'user{flag}')

        return f

    hashed_password = PostGenerated(_hashed_password())

    @staticmethod
    def _is_superuser() -> Callable[..., bool]:
        flag = -1

        def f(*args, **kwargs):
            nonlocal flag
            flag += 1
            return flag == 0

        return f

    is_superuser = PostGenerated(_is_superuser())

    @staticmethod
    def _is_active() -> Callable[..., bool]:
        flag = -1

        def f(*args, **kwargs):
            nonlocal flag
            flag += 1
            return True if flag == 0 else random.choice([True, False])

        return f

    is_active = PostGenerated(_is_active())

    @classmethod
    def registered_at(cls):
        return datetime.datetime.utcnow()

    @staticmethod
    def _activated_at(name: str, values: dict, *args, **kwargs) -> datetime:
        if values['is_active']:
            return datetime.datetime.utcnow()
        return None

    activated_at = PostGenerated(_activated_at)
    last_login_at = None
    accessed_at = None
{% endmacro %}
import asyncio
import random
from typing import Callable

from .auth.models import DBUser
from .auth import AuthFactory
from .models import *
from .db import sessionmanager
from polyfactory import PostGenerated
from polyfactory.factories.sqlalchemy_factory import SQLAlchemyFactory

from .setting import get_settings
setting = get_settings()
SECRET_KEY = setting.secret_key
ALGORITHM = setting.algorithm
ACCESS_TOKEN_EXPIRE_MINUTES = setting.access_token_expire_minutes
auth = AuthFactory.create(SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES)

{% for model in models %}
{% if model.name.camel == 'User' %}
{{ render_user_factory(model) }}
{%- else %}
{{ render_factory(model) }}
{%- endif %}
{% endfor %}


def main():
    async def f():
        async with sessionmanager.session() as session:
            {% for model in models %}
            {{ model.name.camel }}Factory.__async_session__ = session
            {% endfor %}

            {% for root in mock_root %}
            await {{ root }}Factory.create_batch_async(size=10)
            {% endfor %}

    asyncio.run(f())

