#!/usr/bin/env bash
set -euo pipefail

release_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
env_file="/etc/cpt-odoo/odoo.env"
root_dir="/srv/cpt-odoo"
current_link="${root_dir}/current"

if [[ ! -f "$env_file" ]]; then
  echo "Missing $env_file" >&2
  exit 1
fi

set -a
source "$env_file"
set +a

: "${POSTGRES_PASSWORD:?missing POSTGRES_PASSWORD}"
: "${ODOO_ADMIN_PASSWORD:?missing ODOO_ADMIN_PASSWORD}"
: "${ODOO_DOMAIN:?missing ODOO_DOMAIN}"
: "${ODOO_COMMIT:?missing ODOO_COMMIT}"

odoo_image="${ODOO_IMAGE:-docker.m.daocloud.io/library/odoo:19.0}"
postgres_image="${POSTGRES_IMAGE:-docker.m.daocloud.io/library/postgres:17}"
caddy_image="${CADDY_IMAGE:-docker.m.daocloud.io/library/caddy:2.10.0-alpine}"
db_name="${ODOO_DB_NAME:-cpt_odoo_demo}"

mkdir -p "$root_dir/releases" "$root_dir/backups" /etc/cpt-odoo
ln -sfn "$release_dir" "$current_link"

if [[ ! -d "$release_dir/odoo-src/.git" ]]; then
  mkdir -p "$release_dir/odoo-src"
  git -C "$release_dir/odoo-src" init
  git -C "$release_dir/odoo-src" remote add origin https://github.com/odoo/odoo.git
  git -C "$release_dir/odoo-src" fetch --depth 1 origin "$ODOO_COMMIT"
  git -C "$release_dir/odoo-src" checkout --detach FETCH_HEAD
fi
actual_commit="$(git -C "$release_dir/odoo-src" rev-parse HEAD)"
[[ "$actual_commit" == "$ODOO_COMMIT" ]]

podman pull "$postgres_image"
podman pull "$odoo_image"
podman pull "$caddy_image"

podman network exists cpt-odoo-net || podman network create cpt-odoo-net
for volume in cpt-odoo-postgres cpt-odoo-data cpt-odoo-caddy-data cpt-odoo-caddy-config; do
  podman volume exists "$volume" || podman volume create "$volume"
done

cat > /etc/cpt-odoo/odoo.conf <<EOF
[options]
admin_passwd = ${ODOO_ADMIN_PASSWORD}
db_host = 10.89.1.10
db_port = 5432
db_user = odoo
db_password = ${POSTGRES_PASSWORD}
db_name = ${db_name}
dbfilter = ^${db_name}\$
list_db = False
proxy_mode = True
data_dir = /var/lib/odoo
addons_path = /mnt/odoo-src/odoo/addons,/mnt/odoo-src/addons,/mnt/extra-addons
workers = 3
max_cron_threads = 1
limit_memory_soft = 805306368
limit_memory_hard = 1207959552
limit_request = 8192
limit_time_cpu = 600
limit_time_real = 1200
log_level = info
EOF
# The parent directory is root-only. The bind-mounted file itself must remain
# readable by the non-root Odoo user inside the container.
chmod 0644 /etc/cpt-odoo/odoo.conf

cat > /etc/cpt-odoo/Caddyfile <<EOF
{
    admin off
}

https://${ODOO_DOMAIN} {
    encode zstd gzip

    @guide_root path /guide
    redir @guide_root /guide/ 308

    handle_path /guide/* {
        root * /srv/guide
        file_server
    }

    handle {
        reverse_proxy 10.89.1.11:8069
    }

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}
EOF
chmod 0644 /etc/cpt-odoo/Caddyfile
install -m 0644 "$release_dir/guide/sales-quotation-quick-guide.html" "$release_dir/guide/index.html"

podman rm -f cpt-odoo-gateway 2>/dev/null || true
podman rm -f cpt-odoo-app 2>/dev/null || true

podman rm -f cpt-odoo-db 2>/dev/null || true
podman run -d \
  --name cpt-odoo-db \
  --network cpt-odoo-net \
  --ip 10.89.1.10 \
  --restart unless-stopped \
  -e POSTGRES_DB=postgres \
  -e POSTGRES_USER=odoo \
  -e "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}" \
  -v cpt-odoo-postgres:/var/lib/postgresql/data \
  "$postgres_image"

for _ in $(seq 1 60); do
  podman exec cpt-odoo-db pg_isready -U odoo -d postgres >/dev/null 2>&1 && break
  sleep 2
done
podman exec cpt-odoo-db pg_isready -U odoo -d postgres

db_exists="$(podman exec cpt-odoo-db psql -U odoo -d postgres -Atc "SELECT 1 FROM pg_database WHERE datname='${db_name}'")"
if [[ "$db_exists" != "1" ]]; then
  [[ -f "$release_dir/database/${db_name}.dump" ]]
  podman exec cpt-odoo-db createdb -U odoo -T template0 "$db_name"
  podman exec -i cpt-odoo-db pg_restore -U odoo -d "$db_name" --no-owner --no-privileges < "$release_dir/database/${db_name}.dump"
fi

filestore_marker="$(podman run --rm -v cpt-odoo-data:/data "$odoo_image" sh -lc "test -d /data/filestore/${db_name} && echo yes || true")"
if [[ "$filestore_marker" != "yes" ]]; then
  [[ -f "$release_dir/filestore/filestore.tar.gz" ]]
  podman run --rm --user 0 \
    -v cpt-odoo-data:/data \
    -v "$release_dir/filestore:/input:ro,Z" \
    "$odoo_image" \
    sh -lc 'tar -xzf /input/filestore.tar.gz -C /data && chown -R odoo:odoo /data'
fi

podman run -d \
  --name cpt-odoo-app \
  --network cpt-odoo-net \
  --ip 10.89.1.11 \
  --restart unless-stopped \
  -p 127.0.0.1:8069:8069 \
  -v cpt-odoo-data:/var/lib/odoo \
  -v "$release_dir/odoo-src:/mnt/odoo-src:ro,Z" \
  -v "$release_dir/extra-addons:/mnt/extra-addons:ro,Z" \
  -v /etc/cpt-odoo/odoo.conf:/etc/odoo/odoo.conf:ro,Z \
  --entrypoint python3 \
  "$odoo_image" \
  /mnt/odoo-src/odoo-bin -c /etc/odoo/odoo.conf

for _ in $(seq 1 90); do
  curl -fsS -o /dev/null http://127.0.0.1:8069/web/login && break
  sleep 2
done
curl -fsS -o /dev/null http://127.0.0.1:8069/web/login

podman run -d \
  --name cpt-odoo-gateway \
  --network cpt-odoo-net \
  --ip 10.89.1.12 \
  --restart unless-stopped \
  -p 443:443 \
  -p 443:443/udp \
  -v /etc/cpt-odoo/Caddyfile:/etc/caddy/Caddyfile:ro,Z \
  -v "$release_dir/guide:/srv/guide:ro,Z" \
  -v cpt-odoo-caddy-data:/data \
  -v cpt-odoo-caddy-config:/config \
  "$caddy_image"

install -m 0755 "$release_dir/deploy/backup.sh" /usr/local/sbin/cpt-odoo-backup
install -m 0755 "$release_dir/deploy/control.sh" /usr/local/sbin/cpt-odoo-control
install -m 0755 "$release_dir/deploy/update.sh" /usr/local/sbin/cpt-odoo-deploy-release
install -m 0644 "$release_dir/deploy/cpt-odoo-stack.service" /etc/systemd/system/cpt-odoo-stack.service
install -m 0644 "$release_dir/deploy/cpt-odoo-backup.service" /etc/systemd/system/cpt-odoo-backup.service
install -m 0644 "$release_dir/deploy/cpt-odoo-backup.timer" /etc/systemd/system/cpt-odoo-backup.timer
systemctl daemon-reload
systemctl enable cpt-odoo-stack.service cpt-odoo-backup.timer
systemctl start cpt-odoo-backup.timer

printf '%s\n' "$release_dir" > "$root_dir/ACTIVE_RELEASE"
printf 'release=%s\nodoo_commit=%s\ndomain=%s\n' "$(basename "$release_dir")" "$actual_commit" "$ODOO_DOMAIN"
