#!/usr/bin/python
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
# MIT License (see LICENSE)
# ruff: noqa: E402

from __future__ import annotations
from pprint import pp

# TODO: break this down per module
# TODO: generate this by reassembling
DOCUMENTATION = """
---
module: compose
version_added: 1.0.0
short_description: Simplify docker-compose deployments
seealso:
    - name: Compose file reference
      description: Complete reference of the compose file spec.
      link: https://docs.docker.com/reference/compose-file/
description:
    - Easily create docker-compose files using a single module
author:
    - "Luca Bilke (@ssnailed)"
attributes:
    check_mode:
        support: full
    diff_mode:
        support: full
options:
    name:
        description:
            - Name of the compose project to create or modify.
        aliases: [project]
        type: str
    project_dir:
        description:
            - Path to store project directory under.
        type: path
    settings:
        description:
            - Settings/Defaults for the module.
        type: dict
        suboptions:
            default_definition:
                description:
                    - Default definition for all containers.
                    - Overwritten by per-service defaults.
                type: dict
            service_default_definitions:
                description:
                    - Default definitions for each service
                type: dict
                suboptions:
                    custom:
                        description:
                            - Default definitions for custom services.
                        type: dict
                    docker_in_docker:
                        description:
                            - Default definitions for docker in docker services.
                        type: dict
                    docker_socket_proxy:
                        description:
                            - Default definitions for docker socket proxy services.
                        type: dict
                    docker_volume_backupper:
                        description:
                            - Default definitions for docker volume backupper services.
                        type: dict
                    mariadb:
                        description:
                            - Default definitions for MariaDB services.
                        type: dict
                    postgres:
                        description:
                            - Default definitions for PostgreSQL services.
                        type: dict
                    redis:
                        description:
                            - Default definitions for Redis services.
                        type: dict
            service_default_args:
                description:
                    - Default arguments for each service helper.
                type: dict
                suboptions:
                    custom:
                        description:
                            - Default args for custom services.
                        type: dict
                    docker_in_docker:
                        description:
                            - Default args for docker in docker services.
                        type: dict
                    docker_socket_proxy:
                        description:
                            - Default args for docker socket proxy services.
                        type: dict
                    docker_volume_backupper:
                        description:
                            - Default args for docker volume backupper services.
                        type: dict
                    mariadb:
                        description:
                            - Default args for MariaDB services.
                        type: dict
                    postgres:
                        description:
                            - Default args for PostgreSQL services.
                        type: dict
                    redis:
                        description:
                            - Default args for Redis services.
                        type: dict
            label_default_args:
                description:
                    - Default arguments for each label helper.
                type: dict
                suboptions:
                    docker_volume_backupper:
                        description:
                            - Docker Volume Backupper label helper configuration.
                        type: dict
                    traefik_middleware:
                        description:
                            - Traefik Middleware label helper configuration.
                        type: dict
                    traefik_router:
                        description:
                            - Traefik Router label helper configuration.
                        type: dict
                    traefik_service:
                        description:
                            - Traefik Service label helper configuration.
                        type: dict
    services:
        description:
            - Services to create in the project.
        type: dict
        suboptions:
            custom:
                description:
                    - Custom service definition.
                type: list
                elements: dict
                suboptions:
                    name:
                        description:
                            - Name of the service.
                        type: str
                    image:
                        description:
                            - Image to use for service.
                        type: str
                    defaults:
                        description:
                            - Service definition to be overwritten.
                        type: dict
                    overwrite:
                        description:
                            - Service definition to overwrite with.
                        type: dict
                    internal_network:
                        description:
                            - If true, add internal network to service.
                        type: bool
                        default: false
                    label_helpers:
                        description:
                            - Label helper configurations.
                        type: dict
                        suboptions:
                            docker_volume_backupper:
                                description:
                                    - Docker Volume Backupper label helper configuration.
                                type: dict
                                suboptions:
                                    stop:
                                        description:
                                            - If true, stop the container when backing up.
                                        type: bool
                                        default: true
                            traefik_middleware:
                                description:
                                    - Traefik Middleware label helper configuration.
                                type: dict
                                suboptions:
                                    proxy_type:
                                        description:
                                            - Traefik proxy type.
                                        type: str
                                        choices: [http, tcp, udp]
                                        default: http
                                    name:
                                        description:
                                            - Name of the middleware.
                                        type: string
                                    middleware:
                                        description:
                                            - The traefik middleware to use.
                                        type: str
                                        required: true
                                    settings:
                                        description:
                                            - Middleware options.
                                        type: dict
                                        required: true
                            traefik_router:
                                description:
                                    - Traefik Router label helper configuration.
                                type: dict
                                suboptions:
                                    proxy_type:
                                        description:
                                            - Traefik proxy type.
                                        type: str
                                        choices: [http, tcp, udp]
                                        default: http
                                    name:
                                        description:
                                            - Name of the middleware.
                                        type: string
                                    rule:
                                        description:
                                            - Routing rule to match.
                                        type: str
                                        required: true
                                    service:
                                        description:
                                            - Traefik service to point at.
                                        type: str
                                    certresolver:
                                        description:
                                            - Certresolver to use.
                                        type: str
                                    entrypoints:
                                        description:
                                            - Entrypoints to listen on.
                                        type: list
                                        elements: str
                                    middlewares:
                                        description:
                                            - Middlewares to use.
                                        type: list
                                        elements: str
                            traefik_service:
                                description:
                                    - Traefik Service label helper configuration.
                                type: dict
                                suboptions:
                                    proxy_type:
                                        description:
                                            - Traefik proxy type.
                                        type: str
                                        choices: [http, tcp, udp]
                                        default: http
                                    name:
                                        description:
                                            - Name of the middleware.
                                        type: string
                                    port:
                                        description:
                                            - Port to forward to.
                                        type: int
            docker_in_docker:
                description:
                    - Docker-in-Docker service definition.
                type: list
                elements: dict
                suboptions:
                    name:
                        description:
                            - Name of the service.
                        type: str
                    image:
                        description:
                            - Image to use for service.
                        type: str
                    defaults:
                        description:
                            - Service definition to be overwritten.
                        type: dict
                    overwrite:
                        description:
                            - Service definition to overwrite with.
                        type: dict
            docker_socket_proxy:
                description:
                    - Docker Socket Proxy service definition.
                type: list
                elements: dict
                suboptions:
                    name:
                        description:
                            - Name of the service.
                        type: str
                    image:
                        description:
                            - Image to use for service.
                        type: str
                    defaults:
                        description:
                            - Service definition to be overwritten.
                        type: dict
                    overwrite:
                        description:
                            - Service definition to overwrite with.
                        type: dict
                    read_only:
                        description:
                            - If true, only allow read access to the docker socket.
                        type: bool
                        default: true
            docker_volume_backupper:
                description:
                    - Docker Volume Backupper service definition.
                type: list
                elements: dict
                suboptions:
                    name:
                        description:
                            - Name of the service.
                        type: str
                    image:
                        description:
                            - Image to use for service.
                        type: str
                    defaults:
                        description:
                            - Service definition to be overwritten.
                        type: dict
                    overwrite:
                        description:
                            - Service definition to overwrite with.
                        type: dict
                    archive:
                        description:
                            - Directory to store backups in.
                        type: path
                    backup_volumes:
                        description:
                            - List of volume names of volumes to backup.
                        type: list
                        elements: str
            mariadb:
                description:
                    - MariaDB service definition.
                type: list
                elements: dict
                suboptions:
                    name:
                        description:
                            - Name of the service.
                        type: str
                    image:
                        description:
                            - Image to use for service.
                        type: str
                    defaults:
                        description:
                            - Service definition to be overwritten.
                        type: dict
                    overwrite:
                        description:
                            - Service definition to overwrite with.
                        type: dict
                    backup:
                        description:
                            - If true, add labels for the docker volume backupper.
                        type: bool
                    database:
                        description:
                            - Name of database.
                        type: str
                        required: true
                    username:
                        description:
                            - Username for database.
                        type: str
                        required: true
                    password:
                        description:
                            - Password for database.
                        type: str
                        required: true
                    root_password:
                        description:
                            - Root password for database.
                        type: str
            postgres:
                description:
                    - PostgreSQL service definition.
                type: list
                elements: dict
                suboptions:
                    name:
                        description:
                            - Name of the service.
                        type: str
                    image:
                        description:
                            - Image to use for service.
                        type: str
                    defaults:
                        description:
                            - Service definition to be overwritten.
                        type: dict
                    overwrite:
                        description:
                            - Service definition to overwrite with.
                        type: dict
                    backup:
                        description:
                            - If true, add labels for the docker volume backupper.
                        type: bool
                    database:
                        description:
                            - Name of database.
                        type: str
                        required: true
                    username:
                        description:
                            - Username for database.
                        type: str
                        required: true
                    password:
                        description:
                            - Password for database.
                        type: str
                        required: true
            redis:
                description:
                    - Redis service definition.
                type: list
                elements: dict
                suboptions:
                    name:
                        description:
                            - Name of the service.
                        type: str
                    image:
                        description:
                            - Image to use for service.
                        type: str
                    defaults:
                        description:
                            - Service definition to be overwritten.
                        type: dict
                    overwrite:
                        description:
                            - Service definition to overwrite with.
                        type: dict
"""

from importlib.util import find_spec

from ansible.module_utils.basic import AnsibleModule  # pyright: ignore[reportMissingTypeStubs]
from ansible_collections.snailed.ez_compose.plugins.module_utils import (
    common,
    service,
    spec,
)


def main() -> None:
    module = AnsibleModule(
        argument_spec={
            "name": {
                "aliases": ["project"],
                "type": "str",
                "required": True,
            },
            "project_dir": {
                "type": "path",
                "default": "/var/lib/ez_compose",
            },
            "settings": spec.settings_spec(),
            "services": spec.service_argument_spec(),
        },
    )

    if not find_spec("yaml"):
        module.fail_json("PyYAML seems to be missing on host")  # pyright: ignore[reportUnknownMemberType]

    state = common.get_state(module)

    for name, services_params in [(x, y) for x, y in module.params["services"].items() if y]:
        for service_params in services_params:
            helper = getattr(service, name).helper
            state = service.common.run_helper(state, service_params, helper)
            pp(state.after)


if __name__ == "__main__":
    main()