from typing import Literal
from takk.models import SecretClass, Subscriber
from takk.secrets import NatsConfig
from maur.worker import CodingTaskMessage, process_coding_task
from maur.settings import GithubSettings, GitlabSettings, MaurSettings, db_setting_type, MaurLLMSettings
from takk import FastAPIApp, Compute, PubSub, DockerBuild
from takk.docker import ImageBuildArgs

coding_tasks_pubsub = PubSub(
    content_type=CodingTaskMessage,
    subject="maur.tasks",
)

def maur_api(database: Literal["psql", "mysql"] = "psql") -> FastAPIApp:
    return maur_api_with_secrets(
        secrets=[db_setting_type(database)]
    )

def maur_api_with_secrets(secrets: list[SecretClass], compute: Compute | None = None) -> FastAPIApp:
    return FastAPIApp(
        "maur.app",
        health_check="/health",
        secrets=secrets,
        compute=compute or Compute()
    )


def maur_code_subscriber(
    git_provider: Literal["gitlab", "github"] = "github",
    database: Literal["psql", "mysql"] = "psql",
    compute: Compute | None = None
) -> Subscriber[CodingTaskMessage]:

    git_settings = {
        "gitlab": GitlabSettings,
        "github": GithubSettings
    }[git_provider]

    return maur_code_subscriber_with_secrets(
        secrets=[
            db_setting_type(database), MaurSettings, MaurLLMSettings, git_settings, NatsConfig
        ],
        compute=compute
    )

def maur_code_subscriber_with_secrets(
    secrets: list[SecretClass],
    compute: Compute | None = None
) -> Subscriber[CodingTaskMessage]:

    return coding_tasks_pubsub.subscriber(
        process_coding_task,
        image=DockerBuild.default_uv_image(
            image_name="worker-maur", 
            build_args={
                ImageBuildArgs.uv_sync_args: "--locked --no-editable --active --all-groups",
                ImageBuildArgs.apt_packages: "curl ca-certificates bash git libstdc++6 libgcc-s1 unzip jq grep",
                ImageBuildArgs.install_opencode: "true"
            }
        ),
        secrets=secrets,
        compute=compute or Compute(
            mb_memory_limit=1024 * 3
        )
    )
