from collections.abc import Awaitable, Callable, Sequence
from datetime import timedelta
from typing import Any

from csirtmu.core.temporal import TemporalWorkflow
from temporalio import workflow

from csirtmu.perun_sync.config import AppConfig, Config
from csirtmu.perun_sync.temporal.activities import PerunAlphaSyncActivities, PerunSyncActivities
from csirtmu.perun_sync.temporal.workflow_steps import load_s3_data_key


class PerunAlphaSyncWorkflow(TemporalWorkflow):
    @workflow.run
    async def run(self, continue_as_new: bool = True) -> Any:
        cfg: Config = AppConfig.get()
        s3_key = await load_s3_data_key(cfg, cfg.s3_listen_timeout)

        if not s3_key:
            workflow.logger.error("No s3 key found")
            return None

        result = await workflow.execute_activity(
            PerunAlphaSyncActivities.sync_to_database,
            retry_policy=cfg.temporal.retry_policy,
            start_to_close_timeout=timedelta(minutes=30),
            args=(s3_key, cfg.dry_run),
        )
        workflow.logger.info(
            f"Sync result: dry_run={result.dry_run}, inserted={result.inserted}, deleted={len(result.deleted)}"
        )
        if cfg.alias_sync.sync_from_alias_file:
            await workflow.execute_child_workflow(
                "AliasSyncWorkflow",
                retry_policy=cfg.temporal.retry_policy,
                args=(),
            )

        if continue_as_new:
            workflow.continue_as_new()
            return None
        return None

    @classmethod
    def get_activities(cls) -> Sequence[Callable[..., Awaitable[Any]]]:
        config = AppConfig.get()
        return [
            *PerunAlphaSyncActivities(config).get_activities(),
            *PerunSyncActivities(config.s3, config.s3_listen_timeout).get_activities(),
        ]
