#!/bin/bash
SCRIPT_VERSION="1.0.0"
# does it work

## ========================= INSTALL ARRS ===================================

set -euo pipefail

if [ ! -f /root/.post_update ]; then
  echo "Running updates..."

  apt update && apt upgrade -y
  apt autoremove -y
  apt install curl -y
  timedatectl set-timezone America/Los_Angeles
  echo "America/Los_Angeles" > /etc/timezone

  touch /root/.post_update

  # Yellow text output
  echo -e "\033[1;33mAfter reboot re-run the script to complete...\033[0m"
  sleep 4

  reboot
  exit 0
fi

#====================  Varibales ============================

# ================== Install Binutils =======================
sudo apt install binutils

# Defaults
USERNAME="paper"
GROUPNAME="lxc_shares"
GROUPID=10000

echo "Checking if user '$USERNAME' exists..."

if id "$USERNAME" &>/dev/null; then
    echo "User '$USERNAME' already exists. Skipping user creation."
else
    echo "Creating user '$USERNAME' (will prompt for password and info)..."
    adduser "$USERNAME"
fi

echo "Adding user '$USERNAME' to sudo group..."
usermod -aG sudo "$USERNAME"

echo "Checking if group '$GROUPNAME' exists..."
if getent group "$GROUPNAME" >/dev/null; then
    echo "Group '$GROUPNAME' already exists. Skipping group creation."
else
    groupadd -g "$GROUPID" "$GROUPNAME"
    echo "Group '$GROUPNAME' created with GID $GROUPID."
fi

echo "Adding user '$USERNAME' to group '$GROUPNAME'..."
usermod -aG "$GROUPNAME" "$USERNAME"

echo "Done."

# Install dependencies for Docker installation
echo "Installing dependencies for Docker..."
sudo apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common \
    lsb-release \
    gnupg2 \
    jq

# Add Docker’s official GPG key
sudo rm -f /usr/share/keyrings/docker-archive-keyring.gpg
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Set up the Docker stable repository
echo "Setting up Docker repository..."
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Update package index again after adding Docker repo
echo "Updating package index..."
sudo apt update -y

# Install Docker CE
echo "Installing Docker CE..."
sudo apt install -y docker-ce docker-ce-cli containerd.io

# Start and enable Docker service
echo "Starting Docker service..."
sudo systemctl start docker
sudo systemctl enable docker

# Install the latest Docker Compose
echo "Installing Docker Compose..."
LATEST_COMPOSE=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r .tag_name)
sudo curl -L "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Verify Docker and Docker Compose installations
echo "Verifying installations..."
docker --version
docker-compose --version

# Create Docker Compose update script in /opt/scripts/
echo "Creating Docker Compose update script in /opt/scripts/update_compose.sh..."
#sudo mkdir -p /opt/scripts

cat <<EOF | sudo tee /usr/local/bin/update_compose.sh > /dev/null
#!/bin/bash

# Update Docker Compose to the latest version
echo "Updating Docker Compose..."

# Fetch the latest release version from GitHub API
LATEST_COMPOSE=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r .tag_name)

# Download and install the latest Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Make it executable
sudo chmod +x /usr/local/bin/docker-compose

# Verify the installation
docker-compose --version

echo "Docker Compose updated to the latest version."
EOF

# Make the update script executable
sudo chmod +x /usr/local/bin/update_compose.sh

# Create systemd service and timer for running this script every Monday at 2AM
sudo bash -c 'cat <<EOF > /etc/systemd/system/update-compose.service
[Unit]
Description=Update Docker Compose to latest version
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/update-compose.sh
EOF'

sudo bash -c 'cat <<EOF > /etc/systemd/system/update-compose.timer
[Unit]
Description=Run Docker Compose updater every Monday at 2AM

[Timer]
OnCalendar=Mon *-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF'

# Step 4: Reload systemd and enable/start the timer
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable --now update-compose.timer

sudo tee /opt/docker-compose.yml > /dev/null << 'EOF'
services:
  broker:
    image: docker.io/library/redis:7
    restart: unless-stopped
    volumes:
      - redisdata:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

  db:
    image: postgres:18
    restart: always
    volumes:
      - pgdata_v18:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: paperless
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "paperless"]
      interval: 30s
      retries: 3
      timeout: 10s
      start_period: 5s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    mem_limit: 1g
    cpu_shares: 2048
    stop_grace_period: 1m

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
      - gotenberg
      - tika
    ports:
      - "8010:8000"
    healthcheck:
      test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - data:/usr/src/paperless/data
      - /mnt/paperless/media:/usr/src/paperless/media
      - ./export:/usr/src/paperless/export
      - /mnt/paperless/consume:/usr/src/paperless/consume
      - /opt/paperless-ngx/scripts:/usr/src/paperless/scripts
    env_file: docker-compose.env
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
      PAPERLESS_TIKA_ENABLED: 1
      PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
      PAPERLESS_TIKA_ENDPOINT: http://tika:9998
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    mem_limit: 2g
    cpu_shares: 1024

  gotenberg:
    image: docker.io/gotenberg/gotenberg:7.10
    restart: unless-stopped
    command:
      - "gotenberg"
      - "--chromium-disable-javascript=true"
      - "--chromium-allow-list=file:///tmp/.*"
    healthcheck:
      test: ["CMD", "curl", "-fs", "http://localhost:3000/health"]
      interval: 30s
      retries: 3
      timeout: 10s
      start_period: 5s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    mem_limit: 1g
    cpu_shares: 512

  tika:
    build:
      context: /opt
      dockerfile: Dockerfile.tika
    pull_policy: build
#    image: ghcr.io/paperless-ngx/tika:latest
    user: root
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:9998 || exit 1"]
      interval: 30s
      retries: 5
      timeout: 10s
      start_period: 30s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    mem_limit: 1g
    cpu_shares: 512

  nginx:
    image: nginx:latest
    restart: unless-stopped
    depends_on:
      - webserver
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      retries: 3
      timeout: 10s
      start_period: 5s
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - /mnt/paperless/media:/usr/share/nginx/html:ro
    ports:
      - "8080:80"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    mem_limit: 512m
    cpu_shares: 512
    command: >
      /bin/sh -c "
        groupadd -g 10000 lxc_shares || true && \
        usermod -a -G lxc_shares nginx || true && \
        id nginx && \
        nginx -g 'daemon off;'
      "

volumes:
  data:
  pgdata_v18:
  redisdata:
EOF

sudo tee /opt/docker-compose.env > /dev/null << 'EOF'
PAPERLESS_URL=https://paperless.home.rschedules.io
PAPERLESS_CSRF_TRUSTED_ORIGINS=https://paperless.home.rschedules.io
PAPERLESS_TIME_ZONE=America/Los_Angeles
#PAPERLESS_OCR_LANGUAGE=eng
PAPERLESS_MEDIA_ROOT=/usr/src/paperless/media
PAPERLESS_CONSUMPTION_DIR=/usr/src/paperless/consume
PAPERLESS_DATA_DIR=/usr/src/paperless/data
PAPERLESS_CONSUMER_POLLING=10
#PAPERLESS_POST_CONSUME_SCRIPT=/usr/src/paperless/scripts/post-consumption.sh
PAPERLESS_OCR_LANGUAGE=eng+spa
PAPERLESS_SECRET_KEY=Moisture-Spotter-Evacuate-Buddhist3-Scabbed-Detoxify
PAPERLESS_ADMIN_USER=admin
PAPERLESS_ADMIN_PASSWORD=puz7R0AGGSlvvCUb4xMww5
USERMAP_UID=1000
USERMAP_GID=10000
PAPERLESS_OCR_CLEAN=clean
PAPERLESS_FILENAME_FORMAT={{ created_year }}/{{ title }}
PAPERLESS_OCR_MODE=skip
PAPERLESS_OCR_SKIP_ARCHIVE_FILE=never
PAPERLESS_OCR_OUTPUT_TYPE=pdfa
PAPERLESS_OCR_PAGES=1
PAPERLESS_OCR_IMAGE_DPI=300
PAPERLESS_OCR_DESKEW=true
PAPERLESS_OCR_ROTATE_PAGES=true
PAPERLESS_OCR_ROTATE_PAGES_THRESHOLD=12.0
PAPERLESS_CONSUMER_IGNORE_PATTERNS=[".DS_STORE/*", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini"]
PAPERLESS_FORCE_HTTPS=true
PAPERLESS_MAX_UPLOAD_SIZE=104857600
PAPERLESS_WEB_ENABLE_CSRF=true
PAPERLESS_OCR_CONCURRENCY=2
PAPERLESS_LOG_LEVEL=info
EOF

sudo tee /opt/Dockerfile.tika > /dev/null << 'EOF'
FROM ghcr.io/paperless-ngx/tika:latest

USER root

RUN apt-get update && apt-get install -y curl && apt-get clean && rm -rf /var/lib/apt/lists/*

USER tika  # or whatever user Tika runs as, or keep root if okay
EOF

sudo tee /opt/nginx.conf > /dev/null << 'EOF'
# Define the user and worker processes
user nginx;
worker_processes 1;

# Error log and PID file locations
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# Setting up worker connections and buffers
events {
    worker_connections 1024;
}

# HTTP server settings
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Gzip compression for better performance
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/javascript application/json image/svg+xml;

    # Move limit_req_zone here (in the http block)
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

    # Define your server block
    server {
        listen 80;
        server_name localhost;

        # Root directory for serving static files
        root /usr/share/nginx/html;

        # Location block for static files
        location / {
            try_files $uri $uri/ =404;
        }

        # Reverse Proxy to Paperless-ngx Web Application
        location /api/ {
            proxy_pass http://webserver:8000;  # This assumes your webserver container is named "webserver"
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_cache_bypass $http_upgrade;
            proxy_redirect off;
        }

        # Serve media files (PDFs, images, etc.)
        location /media/ {
            alias /mnt/paperless/media/;
            try_files $uri =404;
        }

        # Error pages handling
        error_page 404 /404.html;
        location = /404.html {
            root /usr/share/nginx/html;
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }

        # Security Headers
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        add_header X-Content-Type-Options nosniff;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-XSS-Protection "1; mode=block";
        add_header Referrer-Policy no-referrer-when-downgrade;

        # Rate Limiting (must be inside server block)
        limit_req zone=one burst=20 nodelay;

    }
}
EOF

# Create the folder (including any missing parent folders)
mkdir -p /mnt/paperless/media
mkdir -p /mnt/paperless/consume

# Optional: Set ownership and permissions (adjust as needed)
chown 1000:10000 /mnt/paperless/media
chown 1000:10000 /mnt/paperless/consume
chmod 755 /mnt/paperless/media
chmod 755 /mnt/paperless/consume

touch /mnt/paperless/media/index.html
echo "Paperless media root" > /mnt/paperless/media/index.html

sudo tee /usr/local/bin/paperless_update.sh > /dev/null << 'EOF'
set -e

# System update
echo "Updating system packages..."
sudo apt update && sudo apt upgrade -y
sudo apt autoremove -y
sudo apt clean

# Directory for Paperless docker-compose.yml
cd /opt

# Bring down Docker Compose services
echo "Bringing down Docker Compose services..."
sudo docker-compose down

# Pull latest Docker images
echo "Pulling latest Docker images..."
sudo docker-compose pull

# Start services in detached mode
echo "Starting Docker Compose services..."
sudo docker compose up -d --remove-orphans
#sudo docker-compose up -d

# Clean up unused Docker images
echo "Pruning unused Docker images..."
sudo docker image prune -af

# Remove orphaned/stopped containers
echo "Pruning stopped containers..."
sudo docker container prune -f

# Prompt for reboot with 10-second timeout
echo
read -n 1 -t 10 -p "Do you want to reboot the system now? (y/n): " confirm || confirm=n
echo
if [[ "$confirm" =~ ^[Yy]$ ]]; then
    echo "Rebooting system..."
    sudo reboot
else
    echo "Reboot cancelled. Script completed successfully."
fi
EOF

chmod +x /usr/local/bin/paperless_update.sh

# ========= Script Update Checker =========
sudo tee /usr/local/bin/script_updater.sh > /dev/null <<'EOF'
#!/bin/bash

# ========= Script Update Checker Notes =========
# This script checks the version of a local script against a remote version
# hosted on Nextcloud. If a newer version is found, it downloads and replaces
# the local script, backing up the old one.
#
# Logs updates and errors to /var/log/script-update.log.
# Creates a flag file /var/log/script-updated.flag on successful update.
#
# Designed to be run periodically (e.g., via systemd timer).
# ========================================

LOCAL_SCRIPT="/root/paperless-ngx.sh"   # Change to your actual script path
NEXTCLOUD_URL="https://nextcloud.home.rschedules.io/s/H84d2sZMANBwqnm/download"  # Replace with your actual public Nextcloud link

LOGFILE="/var/log/script-update.log"
FLAGFILE="/var/log/script-updated.flag"

curl_opts=(--fail --silent --show-error --location --max-time 20)

log() {
  echo "[$(date '+%F %T')] $*" >> "$LOGFILE"
}

get_version_from_content() {
  # Use strings to avoid binary grep issues
  strings "$1" | grep '^SCRIPT_VERSION=' | head -n1 | cut -d'"' -f2 || echo ""
}

get_remote_version() {
  tmpf=$(mktemp)
  if curl "${curl_opts[@]}" --output "$tmpf" "$NEXTCLOUD_URL"; then
    log "Successfully downloaded remote file to $tmpf"

    {
      echo "------ START OF REMOTE FILE HEAD ------"
      head -n 20 "$tmpf"
      echo "------ END OF REMOTE FILE HEAD --------"
    } >> "$LOGFILE"

    v=$(get_version_from_content "$tmpf")
    rm -f "$tmpf"
    echo "$v"
  else
    log "Curl failed to download remote script from $NEXTCLOUD_URL"
    rm -f "$tmpf"
    echo ""
  fi
}

get_local_version() {
  if [[ -f "$LOCAL_SCRIPT" ]]; then
    get_version_from_content "$LOCAL_SCRIPT"
  else
    echo ""
  fi
}

version_greater() {
  ver_to_num() {
    printf '%03d%03d%03d\n' $(echo "$1" | tr '.' ' ')
  }
  [[ "$(ver_to_num "$1")" > "$(ver_to_num "$2")" ]]
}

download_and_replace() {
  tmpf=$(mktemp)
  BACKUP_DIR="/root/script-backups"
  mkdir -p "$BACKUP_DIR"

  if curl "${curl_opts[@]}" --output "$tmpf" "$NEXTCLOUD_URL"; then
    chmod +x "$tmpf"
    if [[ -f "$LOCAL_SCRIPT" ]]; then
      # Backup filename with month-day-year format
      backup="${BACKUP_DIR}/$(basename "$LOCAL_SCRIPT").bak.$(date +%m-%d-%Y_%H-%M-%S)"
      cp "$LOCAL_SCRIPT" "$backup"
      log "Backed up old script to $backup"

      # Cleanup backups older than 7 days
      find "$BACKUP_DIR" -name "$(basename "$LOCAL_SCRIPT").bak.*" -type f -mtime +7 -exec rm -f {} \;
      log "Deleted backup files older than 7 days from $BACKUP_DIR"
    fi
    mv "$tmpf" "$LOCAL_SCRIPT"
    log "Updated script to new version"
    touch "$FLAGFILE"
  else
    log "Failed to download updated script"
    rm -f "$tmpf"
  fi
}

check_for_update() {
  local local_ver remote_ver
  local_ver=$(get_local_version)
  remote_ver=$(get_remote_version)

  if [[ -z "$remote_ver" ]]; then
    log "Failed to fetch remote version — cannot proceed."
    echo "Failed to fetch remote version."
    return 1
  fi

  if [[ -z "$local_ver" ]]; then
    log "Local version missing or unreadable, installing remote version $remote_ver"
    download_and_replace
    echo "Installed new script version $remote_ver."
    return 0
  fi

  if version_greater "$remote_ver" "$local_ver"; then
    echo "Update available: remote version $remote_ver"
    log "Update available: remote version $remote_ver > local version $local_ver"
    download_and_replace
  else
    echo "No update needed: local version $local_ver is up to date."
    log "No update needed: remote version $remote_ver <= local version $local_ver"
  fi
}

# Run the check
check_for_update
EOF

# Make the script executable
sudo chmod +x /usr/local/bin/script_updater.sh

echo "Script installed at /usr/local/bin/update-script.sh and made executable."

# Create the systemd service unit
sudo tee /etc/systemd/system/script-updater.service > /dev/null <<EOF
[Unit]
Description=Run script update check

[Service]
Type=oneshot
ExecStart=/usr/local/bin/update-script.sh
EOF

# Create the systemd timer unit
sudo tee /etc/systemd/system/script-updater.timer > /dev/null <<EOF
[Unit]
Description=Run update-script weekly on Mondays at 2 AM

[Timer]
OnCalendar=Mon 02:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Reload systemd and enable the timer
sudo systemctl daemon-reload
sudo systemctl enable --now script-updater.timer
# ========= End Script Update Checker =========

cd /opt

sudo docker-compose up -d

# Ask to delete the script
echo -ne "\nDo you want to delete this install script? (y/n) [auto-cancel in 10s]: "
read -t 10 -n 1 delete_answer
delete_answer=${delete_answer:-n}  # default to no
echo

# Ask to reboot
echo -ne "\nDo you want to reboot? (y/n) [auto-cancel in 10s]: "
read -t 10 -n 1 reboot_answer
reboot_answer=${reboot_answer:-n}  # default to no
echo

# Handle deletion first (before reboot)
if [[ "$delete_answer" =~ ^[Yy]$ ]]; then
    script_path="$(realpath "${BASH_SOURCE[0]}")"
    echo "Deleting install script: $script_path"
    rm -f "$script_path"
    echo "Install script deleted."
else
    echo "Install script not deleted."
fi

# Handle reboot
if [[ "$reboot_answer" =~ ^[Yy]$ ]]; then
    echo "Rebooting now..."
    sleep 2
    reboot
elif [[ "$reboot_answer" =~ ^[Nn]$ ]]; then
    echo "Reboot canceled by user."
else
    echo "No input received. Reboot canceled."
fi
