- name: ensure hypervisor_hostname is present
  fail:
    msg: "hypervisor_hostname must be defined and must be a string"
  when: hypervisor_hostname is not string


- block:
    - name: check connection to hypervisor
      ping:


    - name: unset per-role mount vars
      set_fact:
        container_config_mount: "{{ None }}"
        container_logs_mount: "{{ None }}"
        container_role_config: "{{ {} }}"


    - name: check if role supports prebuilding
      stat:
        path: "{{ (role_path, '..', host_role | d(inventory_hostname), 'tasks/prepare_build.yml') | path_join }}"
      register: result
      delegate_to: localhost


    - name: prepare build environment for role
      include_role:
        name: "{{ host_role | d(inventory_hostname) }}"
        tasks_from: prepare_build
      vars:
        build_dir: "{{ container_build_dir | d(None) }}"
        conf_dir: "{{ (container_config_dir, inventory_hostname) | path_join }}"
        logs_dir: "{{ (container_logs_dir, inventory_hostname) | path_join }}"
      when: result.stat.exists


    - name: set container_cfg
      set_fact:
        container_cfg: "{{ container_default_config | d({}) |
          combine(container_role_config | d({}), recursive=true) |
          combine(container_config | d({}), recursive=true) }}"


    - block:
        - set_fact:
            container_build_dir: "{{ (container_root_build_dir, container_cfg.image) | path_join }}"


        - name: create container build dir
          file:
            path: "{{ container_build_dir }}"
            state: directory


        - name: template dockerfile to build dir
          template:
            src: "{{ container_cfg.image }}.Dockerfile.j2"
            dest: "{{ (container_build_dir, 'Dockerfile') | path_join }}"
            lstrip_blocks: no
            force: yes


        - name: build image from dockerfile
          docker_image:
            name: "{{ container_custom_image_prefix ~ container_cfg.image }}"
            build:
              dockerfile: "{{ (container_build_dir, 'Dockerfile') | path_join }}"
              path: "{{ container_build_dir }}"
            source: build

      when: container_cfg.custom_image | d(false) == true


    - name: create container
      docker_container:
        name: "{{ inventory_hostname }}"
        image: "{{ (container_custom_image_prefix ~ container_cfg.image) if container_cfg.custom_image | d(false) == true
                   else container_cfg.image }}"
        hostname: "{{ inventory_hostname }}"
        command_handling: correct
        network_mode: bridge
        networks: "{{ [] if container_address is not defined else [{'name': 'network', 'ipv4_address': container_address}] }}"
        log_driver: local
        detach: yes
        restart_policy: unless-stopped
        volumes: "{{ [((((container_config_dir, inventory_hostname) | path_join) ~ ':' ~ container_config_mount) if container_config_mount is string else None),
                      ((((container_logs_dir, inventory_hostname) | path_join) ~ ':' ~ container_logs_mount) if container_logs_mount is string else None),
                      (container_cfg.mounts | d(None))] | flatten(levels=1) | select() | list }}"
        privileged: "{{ container_cfg.privileged | d(false) }}"
        devices: "{{ omit if container_cfg.devices is not defined else ([container_cfg.devices] | flatten(levels=1)) }}"
        command: "{{ container_cfg.command | d(omit) }}"
        env: "{{ container_cfg.env | d(omit) }}"
        exposed_ports: "{{ container_cfg.exposed_ports | d(omit) }}"

  delegate_to: "{{ hypervisor_hostname }}"


- block:
    - name: ping container
      ping:

  rescue:
    - name: install python in container
      raw: apk add python3

  when: container_post_build | d(false) == true