---
# showcase/webapp-db.yml — MariaDB setup for the webapp blueprint
#
# Installs MariaDB, creates webapp database and user with random password,
# configures remote access, and stores credentials in /etc/webapp-db-creds
# for the web tier to read via Incus API.

- name: Generate random database password
  ansible.builtin.set_fact:
    db_password: "{{ lookup('password', '/dev/null chars=ascii_letters,digits length=20') }}"

- name: Generate MariaDB setup script
  ansible.builtin.set_fact:
    db_setup_script: |
      #!/bin/bash
      set -e

      echo "=== MariaDB setup starting ==="
      export DEBIAN_FRONTEND=noninteractive

      # Install MariaDB
      apt-get install -y -qq mariadb-server 2>&1 | tail -3
      echo "[OK] MariaDB installed"

      # Start and enable
      systemctl enable mariadb
      systemctl start mariadb
      echo "[OK] MariaDB started"

      # Configure bind address for remote connections
      sed -i 's/^bind-address.*=.*/bind-address = 0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
      systemctl restart mariadb
      echo "[OK] Bind address set to 0.0.0.0"

      # Create database and user
      mysql -u root << 'SQL'
      CREATE DATABASE IF NOT EXISTS webapp;
      CREATE USER IF NOT EXISTS 'webapp'@'%' IDENTIFIED BY '{{ db_password }}';
      GRANT ALL PRIVILEGES ON webapp.* TO 'webapp'@'%';
      FLUSH PRIVILEGES;

      -- Create sample table for the web tier to query
      USE webapp;
      CREATE TABLE IF NOT EXISTS visits (
          id INT AUTO_INCREMENT PRIMARY KEY,
          visitor_ip VARCHAR(45),
          visitor_host VARCHAR(255),
          visited_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      );
      INSERT INTO visits (visitor_ip, visitor_host) VALUES ('setup', '{{ ffsdn_instance_name }}');
      SQL
      echo "[OK] Database 'webapp' and user created"

      # Store credentials for the web tier to read
      MY_IP=$(hostname -I | awk '{print $1}')
      cat > /etc/webapp-db-creds << CREDS
      DB_HOST=${MY_IP}
      DB_PORT=3306
      DB_NAME=webapp
      DB_USER=webapp
      DB_PASS={{ db_password }}
      CREDS
      chmod 644 /etc/webapp-db-creds
      echo "[OK] Credentials stored in /etc/webapp-db-creds"

      echo "=== MariaDB setup complete ==="

- name: Push MariaDB setup script
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/files?path=/tmp/webapp-db-setup.sh"
    method: POST
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    body: "{{ db_setup_script }}"
    headers:
      Content-Type: "application/octet-stream"
      X-Incus-type: "file"
      X-Incus-mode: "0755"
    status_code: [200]

- name: Execute MariaDB setup script
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/exec"
    method: POST
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    body_format: json
    body:
      command: ["/bin/bash", "/tmp/webapp-db-setup.sh"]
      record-output: true
      interactive: false
      wait-for-websocket: false
      environment:
        DEBIAN_FRONTEND: "noninteractive"
    status_code: [202]
    return_content: true
  register: db_setup_exec

- name: Wait for MariaDB setup to complete (up to 5 minutes)
  ansible.builtin.uri:
    url: "{{ incus_api }}{{ db_setup_exec.json.operation }}/wait?timeout=300"
    method: GET
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    return_content: true
    timeout: 320
  register: db_setup_wait
  failed_when: db_setup_wait.json.metadata.status != "Success"

- name: Verify MariaDB setup exit code
  ansible.builtin.assert:
    that:
      - db_setup_wait.json.metadata.metadata.return | int == 0
    fail_msg: "MariaDB setup exited with code {{ db_setup_wait.json.metadata.metadata.return }}"
    success_msg: "MariaDB setup completed successfully"

- name: Verify credentials file was written
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/files?path=/etc/webapp-db-creds"
    method: GET
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    return_content: true
  register: creds_check

- name: Display MariaDB configuration
  ansible.builtin.debug:
    msg: "MariaDB configured: {{ creds_check.content | trim }}"

- name: Clean up setup script
  ansible.builtin.uri:
    url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/exec"
    method: POST
    client_cert: "{{ incus_cert }}"
    client_key: "{{ incus_key }}"
    validate_certs: false
    body_format: json
    body:
      command: ["/bin/rm", "-f", "/tmp/webapp-db-setup.sh"]
      record-output: false
      interactive: false
      wait-for-websocket: false
    status_code: [202]
  ignore_errors: true
