#!/usr/bin/with-contenv bashio
# ==============================================================================
# Start MariaDB service if enabled
# ==============================================================================
MARIADB_DATA=/data/databases
NEW_INSTALL=false

# Init mariadb
if ! bashio::fs.directory_exists "${MARIADB_DATA}"; then
    bashio::log.info "Create a new mariadb initial system"
    mysql_install_db --user=root --datadir="${MARIADB_DATA}" --skip-name-resolve --skip-test-db > /dev/null
    NEW_INSTALL=true
else
    bashio::log.info "Using existing mariadb initial system"
fi

# Redirect log output
rm -f "${MARIADB_DATA}/mariadb.err"
ln -s /proc/1/fd/1 "${MARIADB_DATA}/mariadb.err"

# Start mariadb
bashio::log.info "Starting MariaDB"
mysqld_safe --datadir="${MARIADB_DATA}" --user=root < /dev/null &
MARIADB_PID=$!

# Wait until DB is running
while ! mysql -e "" 2> /dev/null; do
    sleep 1
done

bashio::log.info "Check data integrity and fix corruptions"
mysqlcheck --no-defaults --databases mysql --fix-db-names --fix-table-names || true
mysqlcheck --no-defaults --databases mysql --check --check-upgrade --auto-repair || true
mysqlcheck --no-defaults --all-databases --skip-database=mysql --fix-db-names --fix-table-names || true
mysqlcheck --no-defaults --all-databases --skip-database=mysql --check --check-upgrade --auto-repair || true

bashio::log.info "Ensuring internal database upgrades are performed"
mysql_upgrade --silent

# Set default secure values after initial setup
if bashio::var.true "${NEW_INSTALL}"; then
    # Secure the installation.
    mysql <<-EOSQL
        SET @@SESSION.SQL_LOG_BIN=0;
        DELETE FROM
            mysql.user
        WHERE
            user NOT IN ('mysql.sys', 'mariadb.sys', 'mysqlxsys', 'root', 'mysql', 'proxies_priv')
                OR host NOT IN ('localhost');
        DELETE FROM
            mysql.proxies_priv
        WHERE
            user NOT IN ('mysql.sys', 'mariadb.sys', 'mysqlxsys', 'root', 'mysql', 'proxies_priv')
                OR host NOT IN ('localhost');
        DROP DATABASE IF EXISTS test;
        FLUSH PRIVILEGES;
EOSQL
fi

# Init databases
bashio::log.info "Ensure databases exists"
for database in $(bashio::config "databases"); do
    bashio::log.info "Create database ${database}"
    mysql -e "CREATE DATABASE ${database};" 2> /dev/null || true
done

# Init logins
bashio::log.info "Ensure users exists and are updated"
for login in $(bashio::config "logins|keys"); do
    USERNAME=$(bashio::config "logins[${login}].username")
    PASSWORD=$(bashio::config "logins[${login}].password")

    if mysql -e "SET PASSWORD FOR '${USERNAME}'@'%' = PASSWORD('${PASSWORD}');" 2> /dev/null; then
        bashio::log.info "Update user ${USERNAME}"
    else
        bashio::log.info "Create user ${USERNAME}"
        mysql -e "CREATE USER '${USERNAME}'@'%' IDENTIFIED BY '${PASSWORD}';" 2> /dev/null || true
    fi
done

# Init rights
bashio::log.info "Init/Update rights"
for right in $(bashio::config "rights|keys"); do
    USERNAME=$(bashio::config "rights[${right}].username")
    DATABASE=$(bashio::config "rights[${right}].database")

    if bashio::config.exists "rights[${right}].privileges"; then
        PRIVILEGES=$(bashio::config "rights[${right}].privileges")
        bashio::log.info "Granting ${PRIVILEGES} to ${USERNAME} on ${DATABASE}"
        mysql -e "REVOKE ALL PRIVILEGES ON ${DATABASE}.* FROM '${USERNAME}'@'%';" || true
        mysql -e "GRANT ${PRIVILEGES} ON ${DATABASE}.* TO '${USERNAME}'@'%';" || true
    else
        bashio::log.info "Granting all privileges to ${USERNAME} on ${DATABASE}"
        mysql -e "GRANT ALL PRIVILEGES ON ${DATABASE}.* TO '${USERNAME}'@'%';" 2> /dev/null || true
    fi
done

# Generate service user
if ! bashio::fs.file_exists "/data/secret"; then
    pwgen 64 1 > /data/secret
fi
SECRET=$(</data/secret)
mysql -e "CREATE USER 'service'@'172.30.32.%' IDENTIFIED BY '${SECRET}';" 2> /dev/null || true
mysql -e "CREATE USER 'service'@'172.30.33.%' IDENTIFIED BY '${SECRET}';" 2> /dev/null || true
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'service'@'172.30.32.%' WITH GRANT OPTION;" 2> /dev/null || true
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'service'@'172.30.33.%' WITH GRANT OPTION;" 2> /dev/null || true

# Flush privileges
mysql -e "FLUSH PRIVILEGES;" 2> /dev/null || true

# Send service information to the Supervisor
PAYLOAD=$(\
    bashio::var.json \
        host "$(hostname)" \
        port "^3306" \
        username "service" \
        password "${SECRET}"
)
if bashio::services.publish "mysql" "${PAYLOAD}"; then
    bashio::log.info "Successfully send service information to Home Assistant."
else
    bashio::log.warning "Service message to Home Assistant failed!"
fi

# Register stop
function stop_mariadb() {
    bashio::services.delete "mysql"
    mysqladmin shutdown
    # Successful exit, avoid wait exit status to propagate
    exit 0
}
trap "stop_mariadb" SIGTERM SIGHUP

wait "${MARIADB_PID}"
