---
- name: Create headscale group
  ansible.builtin.group:
    name: "{{ headscale.group }}"
    state: present

- name: Create headscale user
  ansible.builtin.user:
    name: "{{ headscale.user.name }}"
    comment: "{{ headscale.user.comment }}"
    create_home: "{{ headscale.user.create_home }}"
    group: "{{ headscale.group }}"
    groups: "{{ headscale.user.groups }}"
    append: "{{ headscale.user.groups_append }}"
    shell: "{{ headscale.user.shell }}"
    system: "{{ headscale.user.system }}"

- name: Create folder structure
  ansible.builtin.file:
    path: "{{ item }}"
    state: directory
    owner: "{{ headscale.user.name }}"
    group: "{{ headscale.group }}"
    mode: 0700
  loop:
    - /var/lib/headscale
    - /run/headscale
    - /etc/headscale

- name: Install headscale config
  ansible.builtin.template:
    src: config.yaml.j2
    dest: /etc/headscale/config.yaml
    owner: "{{ headscale.user.name }}"
    group: "{{ headscale.group }}"

- name: Create a state folder for Caddy
  ansible.builtin.file:
    path: "{{ caddy.home }}"
    state: directory
    mode: 0700

- name: Install Caddyfile
  ansible.builtin.template:
    src: Caddyfile.j2
    dest: "{{ caddy.home }}/Caddyfile"
    owner: root
    group: root
    mode: 0600
    # multiple validate subcommands is not-a-feature atm...
    # https://github.com/ansible/ansible/issues/72561
    #
    # caddy inline config validation:
    # https://github.com/caddyserver/caddy/issues/3897
    validate: >-
      bash -c
      'caddy fmt "$1"
      && caddy validate --adapter caddyfile --config "$1"'
      - "%s"
  register: caddyfile

- name: Enable services in the firewall
  ansible.posix.firewalld:
    zone: "{{ firewalld_default_zone }}"
    service: "{{ item }}"
    permanent: true
    immediate: true
    state: enabled
  with_items:
    - http
    - https
  when: "firewalld_configure"

- name: Expose gRPC
  ansible.posix.firewalld:
    port: 50443/tcp
    permanent: true
    immediate: true
    state: enabled
  when: "firewalld_configure"

# - name: Install xcaddy
#   ansible.builtin.command:
#     cmd: >
#       go install -v
#       github.com/caddyserver/xcaddy/cmd/xcaddy@{{ caddy.xcaddy_version }}
#     creates: /root/go/bin/xcaddy
#   environment:
#     GOPATH: /usr/bin
#
# - name: Symlink xcaddy to /bin
#   ansible.builtin.file:
#     src: /root/go/bin/xcaddy
#     dest: /usr/bin/xcaddy
#     state: link
#
# - name: Build Caddy + njalla plugin
#   ansible.builtin.command:
#     cmd: >
#       xcaddy build
#       --with github.com/caddy-dns/njalla
#       --output /usr/bin/nucaddy
#     creates: /usr/bin/nucaddy
#   environment:
#     GOPATH: /usr/bin
#     XCADDY_GO_BUILD_FLAGS: "-ldflags '-w s'"
#     XCADDY_SKIP_CLEANUP: 1

- name: Install caddy-hs systemd service
  ansible.builtin.template:
    src: caddy-hs.service.j2
    dest: /etc/systemd/system/caddy-hs.service
    owner: root
    group: root
  register: caddysystemd

- name: Enable + start caddy-hs systemd service
  ansible.builtin.systemd:
    name: caddy-hs
    state: started
    enabled: true
    daemon_reload: true
  notify: Restart caddy-hs

- name: Fetch crt,key
  ansible.builtin.fetch:
    src: "{{ caddy.home }}/.local/share/caddy/certificates/{{ caddy.acme_url }}/{{ headscale.dns.base_domain }}/{{ headscale.dns.base_domain}}.{{ item }}"
    dest: "/tmp/.{{ headscale.dns.base_domain }}-certs"
  loop:
    - crt
    - key
  when: caddyfile.changed or caddysystemd.changed
  register: fetchcrt

- name: Copy to altcrtpath
  ansible.builtin.copy:
    src: "/tmp/.{{ headscale.dns.base_domain }}-certs/{{ ansible_host }}{{ caddy.home }}/.local/share/caddy/certificates/{{ caddy.acme_url }}/{{ headscale.dns.base_domain }}/{{ headscale.dns.base_domain}}.{{ item }}"
    dest: "{{ headscale.altcrtpath }}/"
  loop:
    - crt
    - key
  when: fetchcrt.changed

- name: Run headscale container
  containers.podman.podman_container:
    name: headscale
    state: started
    recreate: true
    image: "docker.io/headscale/headscale:{{ headscale.version }}"
    ports: "{{ headscale.ports }}"
    cap_add: "{{ headscale.cap_add }}"
    restart_policy: always
    volume:
      - "{{ headscale.homedir }}:/var/lib/headscale:Z"
      - "{{ headscale.rundir }}:/var/run/headscale:Z"
      - "{{ headscale.etcdir }}:/etc/headscale:Z"
      - "{{ headscale.altcrtpath }}:{{ headscale.le.certsroot }}:Z,ro"
    command: headscale serve
  vars:
    crtpath: "{{ headscale.altcrtpath }}/{{ headscale.dns.base_domain }}"
  when: caddyfile.changed or caddysystemd.changed or fetchcrt.changed

- name: Run headscale-ui container
  containers.podman.podman_container:
    name: headscale-ui
    state: started
    recreate: true
    image: "ghcr.io/gurucomputing/headscale-ui:{{ headscale.ui.version }}"
    ports: "{{ headscale.ui.ports }}"
    restart_policy: always
  when: caddyfile.changed or caddysystemd.changed or fetchcrt.changed
...