---
- hosts: apt
  vars:
    rootUser: root

    dependencies:
      - build-essential
      - cowbuilder
      - debhelper
      - devscripts
      - dh-golang
      - distro-info
      - dpkg-dev
      - git
      - pbuilder
      - nginx

    distributions:
      - codename: bookworm
        version: 12
      - codename: bullseye
        version: 11

  roles:
    - ../roles/reprepro
    - ../roles/gpg

  tasks:
    - name: Install dependencies
      become: true
      ansible.builtin.apt:
        name: "{{ dependencies }}"
        state: present

    - name: Check if NGINX needs to be configured
      become: true
      ansible.builtin.shell: "ls /etc/nginx/sites-enabled | grep 'apt.cgrates.org.vhost'"
      ignore_errors: true
      register: nginxConfig

    - name: Configure NGINX server
      ansible.builtin.include_tasks: nginx.yaml
      when: nginxConfig.stdout_lines | length < 1

    - name: Enable and start nginx
      ansible.builtin.systemd:
        name: nginx
        state: started
        masked: false
        enabled: true

    - name: Install Go
      ansible.builtin.import_role:
        name: ../roles/go
      vars:
        go_clean_build_cache: true
        go_clean_modcache: true

    - name: Create chroots
      become: true
      ansible.builtin.command: >-
        cowbuilder --create --distribution {{ item.codename }} --architecture amd64
        --basepath /var/cache/pbuilder/base-{{ item.codename }}+go.cow
        --mirror http://deb.debian.org/debian --components main
      args:
        creates: "/var/cache/pbuilder/base-{{ item.codename }}+go.cow"
      with_items: "{{ distributions }}"

    - name: Check Go tarball
      ansible.builtin.stat:
        path: "/usr/local/src/{{ go_tarball }}"
      register: downloaded_go_tarball

    - name: Download Go tarball
      become: true
      ansible.builtin.get_url:
        url: "{{ go_download_url }}"
        dest: "/usr/local/src/{{ go_tarball }}"
        checksum: "sha256:{{ go_checksum }}"
        mode: "0644"
      when: not downloaded_go_tarball.stat.exists

    - name: Check Go version in chroots
      become: true
      ansible.builtin.command: >-
        chroot /var/cache/pbuilder/base-{{ item.codename }}+go.cow
        bash -c "GOROOT=/usr/local/go /usr/local/go/bin/go version"
      register: chroot_go_version
      ignore_errors: true
      with_items: "{{ distributions }}"
      changed_when: false

    - name: Remove old Go from chroots when version differs
      become: true
      ansible.builtin.file:
        path: "/var/cache/pbuilder/base-{{ item.item.codename }}+go.cow/usr/local/go"
        state: absent
      with_items: "{{ chroot_go_version.results }}"
      when:
        - item.rc == 0
        - go_version not in item.stdout

    - name: Install Go in chroots
      become: true
      ansible.builtin.unarchive:
        src: "/usr/local/src/{{ go_tarball }}"
        dest: "/var/cache/pbuilder/base-{{ item.codename }}+go.cow/usr/local"
        copy: false
        creates: "/var/cache/pbuilder/base-{{ item.codename }}+go.cow/usr/local/go"
      with_items: "{{ distributions }}"

    - name: Customize .bashrc in chroots
      become: true
      ansible.builtin.template:
        src: bashrc.j2
        dest: "/var/cache/pbuilder/base-{{ item.codename }}+go.cow/root/.bashrc"
        mode: "0644"
        owner: root
        group: root
      with_items: "{{ distributions }}"

    - name: Customize .pbuilderrc
      ansible.builtin.template:
        src: pbuilderrc.j2
        dest: "/home/{{ user }}/.pbuilderrc"
        mode: "0644"

    - name: Check update timestamp
      ansible.builtin.stat:
        path: "/var/cache/pbuilder/update-timestamp"
      register: update_timestamp

    - name: Update chroots
      become: true
      ansible.builtin.command: "cowbuilder --update --basepath /var/cache/pbuilder/base-{{ item.codename }}+go.cow"
      with_items: "{{ distributions }}"
      when: not update_timestamp.stat.exists or update_timestamp.stat.mtime <= (ansible_date_time.epoch | int - 86400)
      register: update_chroots

    - name: Update timestamp
      become: true
      ansible.builtin.file:
        path: /var/cache/pbuilder/update-timestamp
        state: touch
        mode: "0644"
      when: update_chroots.changed

    ###########################################################################################################################
    ###########################################################################################################################
    - name: Set up cgrates
      ansible.builtin.import_role:
        name: ../../roles/cgrates
      vars:
        cgrates_bin_path: ""
        cgrates_dbs: []
        cgrates_dependencies: []

    - name: Sync the go mod with vendor
      ansible.builtin.command:
        cmd: go mod vendor
        chdir: "{{ cgrates_dir }}"
      environment:
        PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin"

    - name: Get current Git tag
      ansible.builtin.command: git tag -l --points-at HEAD
      args:
        chdir: "{{ cgrates_dir }}"
      register: git_tag_result

    ###########################################################################################################################
    ###########################################################################################################################

    - block:
        - name: Generate packages
          ansible.builtin.command: 'env "DISTRIBUTION={{ item.codename }}" make -C packages deb'
          args:
            chdir: "{{ cgrates_dir }}"
          with_items: "{{ distributions }}"

        - name: Find generated package files
          ansible.builtin.find:
            paths: "/home/{{ user }}/go/src/github.com/cgrates"
            patterns:
              - cgrates_*
              - cgrates-dbgsym_*
            file_type: file
          register: package_files

        - name: Move package files to incoming directory
          become: true
          ansible.builtin.command: mv {{ item.path }} {{ reprepro_basedir }}/incoming/
          args:
            creates: "{{ reprepro_basedir }}/incoming/{{ item.path | basename }}"
            removes: "{{ item.path }}"
          with_items: "{{ package_files.files }}"
          when: package_files.matched > 0

        - name: Find Debian package changes files (.changes) for each distribution
          ansible.builtin.find:
            paths: "{{ reprepro_basedir }}/incoming"
            patterns: "*~deb{{ item.version }}u1_amd64.changes"
            file_type: file
          register: changes_files
          with_items: "{{ distributions }}"

        - name: Validate that each distribution has exactly one .changes file for proper reprepro inclusion
          ansible.builtin.fail:
            msg: "Debian packaging error: Expected exactly 1 .changes file for {{ item.item.codename }}, found {{ item.matched }}. Each distribution should have a single .changes file for proper repository inclusion."
          when: item.matched != 1
          with_items: "{{ changes_files.results }}"

        - name: Include the packages with reprepro
          become: true
          ansible.builtin.shell:
            cmd: reprepro -Vb . --ignore=wrongdistribution include {{ cgrates_branch }}-{{ item.item.codename }} {{ item.files[0].path }}
            chdir: "{{ reprepro_basedir }}"
          with_items: "{{ changes_files.results }}"

        - name: Copy the file to PKG server
          ansible.builtin.command: "scp {{ reprepro_basedir }}/incoming/{{ item.path | basename }} {{ pkgAddr }}:/tmp/"
          with_items: "{{ package_files.files }}"

      rescue:
        - name: Find all files in incoming directory
          ansible.builtin.find:
            paths: "{{ reprepro_basedir }}/incoming"
            file_type: file
          register: all_incoming_files

        - name: Display files for debugging
          ansible.builtin.debug:
            msg: "{{ all_incoming_files.files | map(attribute='path') | list }}"

        - name: Find build log files
          ansible.builtin.find:
            paths: "{{ reprepro_basedir }}/incoming"
            patterns: "*.build"
            file_type: file
          register: build_log_files
          ignore_errors: true

        - name: Ensure log directory exists
          become: true
          ansible.builtin.file:
            path: "/tmp/ansible_build_logs"
            state: directory
            mode: "0755"
          ignore_errors: true

        - name: Copy build logs to a safe location
          become: true
          ansible.builtin.copy:
            src: "{{ item.path }}"
            dest: "/tmp/ansible_build_logs/{{ item.path | basename }}"
            remote_src: true
          with_items: "{{ build_log_files.files }}"
          ignore_errors: true
          when: build_log_files.matched > 0

        - name: Remove chroot environments
          become: true
          ansible.builtin.file:
            path: "/var/cache/pbuilder/base-{{ item.codename }}+go.cow"
            state: absent
          with_items: "{{ distributions }}"

        - name: Remove update timestamp
          become: true
          ansible.builtin.file:
            path: "/var/cache/pbuilder/update-timestamp"
            state: absent

        - name: Fail with error
          ansible.builtin.fail:
            msg: "Task failed - see original error above. Build logs saved to /tmp/ansible_build_logs/ if available."

      always:
        - name: Clean the incoming folder
          become: true
          ansible.builtin.file:
            path: "{{ reprepro_basedir }}/incoming"
            state: absent

        - name: Remove leftover package files
          ansible.builtin.file:
            path: "{{ item }}"
            state: absent
          with_fileglob:
            - "/home/{{ user }}/go/src/github.com/cgrates/cgrates_*"
            - "/home/{{ user }}/go/src/github.com/cgrates/cgrates-dbgsym_*"

- hosts: pkg
  vars:
    nginx_user: "www-data"
    cgrates_branch: "1.0"
    distributions:
      - codename: bookworm
        version: 12
      - codename: bullseye
        version: 11
  tasks:
    - name: Add user to www-data group
      become: true
      ansible.builtin.user:
        name: "{{ user }}"
        groups: "{{ nginx_user }}"
        append: true

    - name: Create directory
      become: true
      ansible.builtin.file:
        path: /var/packages/deb/{{ cgrates_branch }}/{{ item.codename }}
        state: directory
        mode: "0775"
        owner: "{{ nginx_user }}"
        group: "{{ nginx_user }}"
      with_items: "{{ distributions }}"

    - name: Remove symlink from current deb package
      ansible.builtin.file:
        path: /var/packages/deb/{{ cgrates_branch }}/{{ item.codename }}/cgrates_current_amd64.deb
        state: absent
      with_items: "{{ distributions }}"

    - name: Move the new package to /var/packages/deb
      become: true
      ansible.builtin.shell: "mv /tmp/cgrates_*~deb{{ item.version }}u1*.deb /var/packages/deb/{{ cgrates_branch }}/{{ item.codename }}/"
      with_items: "{{ distributions }}"

    - name: Find all package files
      become: true
      ansible.builtin.find:
        path: "/var/packages/deb/{{ cgrates_branch }}/"
        patterns: "*.deb"
        recurse: true
      register: package_files

    - name: Set ownership and permissions for moved files
      become: true
      ansible.builtin.file:
        path: "{{ item.path }}"
        owner: "{{ nginx_user }}"
        group: "{{ nginx_user }}"
        mode: "0644"
      loop: "{{ package_files.files }}"

    - name: Find package files per distribution
      become: true
      ansible.builtin.find:
        path: "/var/packages/deb/{{ cgrates_branch }}/{{ item.codename }}/"
        patterns: cgrates_*_amd64.deb
      with_items: "{{ distributions }}"
      register: distribution_package_files

    - ansible.builtin.set_fact:
        latest_file: "{{ item.files | sort(attribute='mtime', reverse=true) | first }}"
      with_items: "{{ distribution_package_files.results }}"
      register: latest_files

    - name: Create the new symlink cgrates_current_amd64.deb
      become: true
      ansible.builtin.file:
        src: "{{ item.ansible_facts.latest_file.path }}"
        dest: "/var/packages/deb/{{ cgrates_branch }}/{{ item.item.item.codename }}/cgrates_current_amd64.deb"
        state: link
      with_items: "{{ latest_files.results }}"
