#!/bin/bash
set -e

# Переменные/вычисления, экспортируемые в SEML
DATA_DIR="/var/lib/allpkgpath"
SELF_NAME=$(basename "$0")
DB_ALLPKG="$DATA_DIR/allpkgpath.sqlite3"
# Точка выхода при вызове из SEML
[ "$__SEML__" ] && return

# deb-control
# [<{{SOURCE_DIR}}/{{PACKAGE_NAME}}]
# Section: utils
# Depends: coreutils, sqlite3
# Description:'
#  Write information about all installed deb-packages
#  into file {{DB_ALLPKG}}
#  .
#  Usage:
#   {{SELF_NAME}} [file.sqlite3]
# '
# DIRS:'
#   {{DATA_DIR}}
# '
# /deb-control

DB_FILES="${1:-$DB_ALLPKG}"

if [[ $EUID -ne 0 ]]; then
    echo "Error: run this script as root"
    exit 1
fi

# на всякий случай создаём рабочую папку пакета
mkdir -p "$DATA_DIR"

rm -f "$DB_FILES"

sqlite3 "$DB_FILES" <<'SQL'
CREATE TABLE files (
    path    TEXT PRIMARY KEY,
    package TEXT NOT NULL
);

CREATE INDEX idx_files_package ON files(package);

CREATE TABLE dirs (
    path    TEXT PRIMARY KEY,
    package TEXT NOT NULL,
    cnt     INTEGER NOT NULL DEFAULT 1
);

CREATE INDEX idx_dirs_package ON dirs(package);

CREATE TABLE packages (
    package TEXT PRIMARY KEY,
    removed INTEGER NOT NULL DEFAULT 0
);
SQL

TMP_FILES_SQL=$(mktemp)
TMP_DIRS_SQL=$(mktemp)
TMP_PACKAGES_SQL=$(mktemp)
trap 'rm -f "$TMP_FILES_SQL" "$TMP_DIRS_SQL" "$TMP_PACKAGES_SQL"' EXIT

echo 'BEGIN;' >"$TMP_FILES_SQL"
echo 'BEGIN;' >"$TMP_DIRS_SQL"
echo 'BEGIN;' >"$TMP_PACKAGES_SQL"

# Держим файлы открытыми через fd, чтобы не делать open/close на каждый путь.
exec 3>>"$TMP_FILES_SQL"
exec 4>>"$TMP_DIRS_SQL"
exec 5>>"$TMP_PACKAGES_SQL"

dpkg-query -W -f='${binary:Package}\n' |
while IFS= read -r package; do
    echo "Processing $package..." >&2
    package_sql=${package//\'/\'\'}
    printf "INSERT OR IGNORE INTO packages(package) VALUES ('%s');\n" \
        "$package_sql" >&5

    dpkg -L "$package" |
    while IFS= read -r path; do
        # Экранируем одинарные кавычки для SQL.
        path_sql=${path//\'/\'\'}

        if [[ -d "$path" ]]; then
            printf "INSERT INTO dirs(path, package) VALUES ('%s', '%s') ON CONFLICT(path) DO UPDATE SET cnt = cnt + 1, package = excluded.package;\n" \
                "$path_sql" "$package_sql" >&4
        else
            printf "INSERT OR IGNORE INTO files(path, package) VALUES ('%s', '%s');\n" \
                "$path_sql" "$package_sql" >&3
        fi
    done
done

echo 'COMMIT;' >&3
echo 'COMMIT;' >&4
echo 'COMMIT;' >&5
exec 3>&-
exec 4>&-
exec 5>&-

echo "Making files table..." >&2
sqlite3 "$DB_FILES" <"$TMP_FILES_SQL"

echo "Making dirs table..." >&2
sqlite3 "$DB_FILES" <"$TMP_DIRS_SQL"

echo "Making packages table..." >&2
sqlite3 "$DB_FILES" <"$TMP_PACKAGES_SQL"

rm -f "$TMP_FILES_SQL" "$TMP_DIRS_SQL" "$TMP_PACKAGES_SQL"
trap - EXIT

echo "Database: $DB_FILES" >&2


exit 0
# deb-postrm
#!/bin/bash

if [[ "$1" == "purge" ]]; then
    rm -f /var/lib/allpkgpath/allpkgpath.sqlite3
    rmdir --ignore-fail-on-non-empty /var/lib/allpkgpath 2>/dev/null || true
fi

exit 0
# /deb-postrm
