---
# MotoVaultPro Production Runner Deployment Playbook
# Deploys act_runner for Gitea Actions on the production server
#
# Usage:
#   ansible-playbook -i inventory.yml deploy-production-runner.yml --ask-become-pass
#
# Required variables (set in inventory or pass with -e):
#   gitea_runner_token: Registration token from Gitea
#   gitea_registry_token: Access token for package registry
#   gitea_username: Username for registry login (default: egullickson)
#
# Optional variables:
#   act_runner_version: Version of act_runner to install (default: 0.2.13)
#   gitea_instance: Gitea server URL (default: https://git.motovaultpro.com)

- name: Deploy MotoVaultPro Production Runner
  hosts: production
  become: true
  vars:
    act_runner_version: "0.2.13"
    gitea_instance: "https://git.motovaultpro.com"
    gitea_username: "egullickson"
    runner_name: "Production Server"
    runner_labels: "prod:host"
    app_root: "/opt/motovaultpro"
    repo_url: "https://git.motovaultpro.com/egullickson/motovaultpro.git"

  tasks:
    # ============================================
    # System Update and Prerequisites
    # ============================================
    - name: Update apt cache
      apt:
        update_cache: true
        cache_valid_time: 3600

    - name: Upgrade all packages
      apt:
        upgrade: dist
      when: upgrade_packages | default(false)

    - name: Install required packages
      apt:
        name:
          - curl
          - git
          - ca-certificates
          - gnupg
          - jq
          - nodejs
        state: present

    # ============================================
    # Docker Installation
    # ============================================
    - name: Create keyrings directory
      file:
        path: /etc/apt/keyrings
        state: directory
        mode: '0755'

    - name: Add Docker GPG key
      shell: |
        curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
        chmod a+r /etc/apt/keyrings/docker.gpg
      args:
        creates: /etc/apt/keyrings/docker.gpg

    - name: Get Ubuntu codename
      command: lsb_release -cs
      register: ubuntu_codename
      changed_when: false

    - name: Get architecture
      command: dpkg --print-architecture
      register: system_arch
      changed_when: false

    - name: Add Docker repository
      apt_repository:
        repo: "deb [arch={{ system_arch.stdout }} signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ubuntu_codename.stdout }} stable"
        state: present
        filename: docker

    - name: Install Docker packages
      apt:
        name:
          - docker-ce
          - docker-ce-cli
          - containerd.io
          - docker-buildx-plugin
          - docker-compose-plugin
        state: present
        update_cache: true

    - name: Ensure Docker service is running
      systemd:
        name: docker
        state: started
        enabled: true

    # ============================================
    # act_runner Installation
    # ============================================
    - name: Download act_runner binary
      get_url:
        url: "https://gitea.com/gitea/act_runner/releases/download/v{{ act_runner_version }}/act_runner-{{ act_runner_version }}-linux-amd64"
        dest: /usr/local/bin/act_runner
        mode: '0755'

    - name: Verify act_runner installation
      command: act_runner --version
      register: act_runner_check
      changed_when: false

    - name: Display act_runner version
      debug:
        msg: "act_runner version: {{ act_runner_check.stdout }}"

    # ============================================
    # act_runner User Setup
    # ============================================
    - name: Create act_runner user
      user:
        name: act_runner
        system: true
        shell: /bin/bash
        create_home: true

    - name: Add act_runner to docker group
      user:
        name: act_runner
        groups: docker
        append: true

    - name: Configure passwordless sudo for act_runner
      copy:
        dest: /etc/sudoers.d/act_runner
        content: |
          # Allow act_runner to run commands without password for CI/CD operations
          # This is required because Gitea Actions runners don't have a TTY
          act_runner ALL=(ALL) NOPASSWD: ALL
        mode: '0440'
        validate: 'visudo -cf %s'

    - name: Create act_runner config directory
      file:
        path: /etc/act_runner
        state: directory
        owner: act_runner
        group: act_runner
        mode: '0755'

    # ============================================
    # Runner Registration
    # ============================================
    - name: Check if runner is already registered
      stat:
        path: /etc/act_runner/.runner
      register: runner_registered

    - name: Deploy act_runner config
      template:
        src: config.yaml.j2
        dest: /etc/act_runner/config.yaml
        owner: act_runner
        group: act_runner
        mode: '0644'
      notify: Restart act_runner

    - name: Register runner with Gitea
      shell: |
        su - act_runner -c "cd /etc/act_runner && act_runner register --no-interactive \
          --instance {{ gitea_instance }} \
          --token {{ gitea_runner_token }} \
          --name '{{ runner_name }}' \
          --labels '{{ runner_labels }}'"
      when: not runner_registered.stat.exists
      no_log: true

    # ============================================
    # Systemd Service
    # ============================================
    - name: Create act_runner systemd service
      copy:
        dest: /etc/systemd/system/act_runner.service
        content: |
          [Unit]
          Description=Gitea Actions Runner
          After=docker.service network.target

          [Service]
          ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml
          WorkingDirectory=/etc/act_runner
          User=act_runner
          Group=act_runner
          Restart=always
          RestartSec=10

          [Install]
          WantedBy=multi-user.target
        mode: '0644'
      notify: Restart act_runner

    - name: Enable and start act_runner service
      systemd:
        name: act_runner
        state: started
        enabled: true
        daemon_reload: true

    # ============================================
    # Production Environment Setup
    # ============================================
    - name: Create application directory
      file:
        path: "{{ app_root }}"
        state: directory
        owner: act_runner
        group: act_runner
        mode: '0755'

    - name: Clone repository
      shell: |
        if [ ! -d "{{ app_root }}/.git" ]; then
          su - act_runner -c "git clone {{ repo_url }} {{ app_root }}"
        fi
      args:
        creates: "{{ app_root }}/.git"

    - name: Create data directories
      file:
        path: "{{ app_root }}/{{ item }}"
        state: directory
        owner: '1001'
        group: '1001'
        mode: '0755'
      loop:
        - data/backups
        - data/documents

    # ============================================
    # Docker Registry Authentication
    # ============================================
    - name: Create Docker config directory for act_runner
      file:
        path: /home/act_runner/.docker
        state: directory
        owner: act_runner
        group: act_runner
        mode: '0700'

    - name: Configure Docker registry authentication
      copy:
        dest: /home/act_runner/.docker/config.json
        content: |
          {
            "auths": {
              "git.motovaultpro.com": {
                "auth": "{{ (gitea_username + ':' + gitea_registry_token) | b64encode }}"
              }
            }
          }
        owner: act_runner
        group: act_runner
        mode: '0600'
      no_log: true
      when: gitea_registry_token is defined

    # ============================================
    # Remove Legacy Docker Cleanup (was destroying volumes)
    # ============================================
    - name: Remove legacy Docker cleanup cron job
      cron:
        name: "Docker cleanup"
        state: absent

    - name: Remove legacy Docker cleanup script
      file:
        path: /usr/local/bin/docker-cleanup.sh
        state: absent

    # ============================================
    # Production-Specific Security Hardening
    # ============================================
    - name: Set restrictive permissions on secrets
      file:
        path: "{{ app_root }}/secrets"
        state: directory
        owner: act_runner
        group: act_runner
        mode: '0700'
        recurse: true

    - name: Ensure no world-readable files in secrets
      shell: find {{ app_root }}/secrets -type f -exec chmod 600 {} \;
      changed_when: false

  handlers:
    - name: Restart act_runner
      systemd:
        name: act_runner
        state: restarted
        daemon_reload: true

  post_tasks:
    - name: Display runner status
      command: systemctl status act_runner
      register: runner_status
      changed_when: false
      ignore_errors: true

    - name: Show deployment summary
      debug:
        msg: |
          ================================================
          Production Runner Deployment Complete
          ================================================
          Runner Name: {{ runner_name }}
          Runner Labels: {{ runner_labels }}
          Gitea Instance: {{ gitea_instance }}
          Application Root: {{ app_root }}

          Verify at: {{ gitea_instance }}/egullickson/motovaultpro/settings/actions/runners

          Useful commands:
            sudo systemctl status act_runner
            sudo journalctl -u act_runner -f
            docker ps

          IMPORTANT: Ensure secrets are configured in:
            {{ app_root }}/secrets/app/
          ================================================
