#!/bin/bash
# *******************************************************************
# **  @file eisman_init.sh - build installed package database
# **
# **  Creation:     2013-01-12 dv
# **  Last update:  $Id: eisman_init.sh 42826 2016-08-13 19:44:23Z hbfl $
# **
# **  Copyright (c) 2013-2016 the eisfair team, team(at)eisfair(dot)org
# **
# **  This program is free software; you can redistribute it and/or modify
# **  it under the terms of the GNU General Public License as published by
# **  the Free Software Foundation; either version 2 of the License, or
# **  (at your option) any later version.
# *******************************************************************

. /var/install/include/eislib
. /var/install/include/eismanlib


# *******************************************************************
# **  show help on arguments and possible options
# **  @param  n/a
# **  @return n/a
# *******************************************************************

show_help()
{
cat <<EOF

(Re)build installed package database
Normally this is run only once right after installation of eisman!

usage: eisman init [OPTIONS]

options:
   --help      show this help screen

EOF
}


# *******************************************************************
# **  read index file line by line, check if package meets current system
# **  and fetch the info header file if it is't already in the local cache.
# **  The files are converted into record format!
# **  Further an entry for every package is added to the package database
# **  (without any respect to the fact if it is a new entry or not). Before
# **  doing that, the contents of the package database is cleared.
# **  @param  n/a
# **  @return n/a
# *******************************************************************

update_record_files()
{
    # show what we are doing
    mecho --info '(Re)building installed package database ...'

    # overwrite existing database
    > "${EISMAN_PATH}/installed.db"

    # search package files and loop over result
    local files=$(ls /var/install/packages/*)
    for file in ${files}
    do
        echo "=> Adding ${file} ..."

        success="1"

        package=$(basename "${file}")

        # lookup version form package info file
        version=$(grep "<version>" "${file}" |
                  sed -ne 's#[ \t]*</*version>[ \t]*##gp')

        # try to locate a record file already present in info path
        recfile=$(find "/var/lib/eisman/info/${package}/${version}/" \
                  -name "*.rec"                                      \
                  -type f 2> /dev/null |                            \
                  head -n 1)

        # if record file has been found, copy it to installed.db
        if [ -n "${version}" ] && [ -n "${recfile}" ]
        then
            cat "${recfile}" >> "${EISMAN_PATH}/installed.db"
            if [ "$?" != "0" ]
            then
                success="0"
            fi
        else
            # copy to temporary file
            "${EISMAN_BIN_PATH}/eisman_info_to_db.sh" \
                --url     "taken_from_${file}" \
                "${file}" \
                "/tmp/tmprec$$"
            if [ "$?" != "0" ]
            then
                success="0"
            fi

            # add entry to package db
            if [ "${success}" = "1" ]
            then
                cat "/tmp/tmprec$$" >> "${EISMAN_PATH}/installed.db"
                if [ "$?" != "0" ]
                then
                    success="0"
                fi
            fi

            # remove temporary file
            rm -f "/tmp/tmprec$$"
        fi

        # show result
        if [ "${success}" = "1" ]
        then
            mecho --ok
        else
            mecho --fail
        fi
    done

    # we are ready !
    mecho --info "Done!"
}


# *******************************************************************
# **  perform format update from version 1.0 to 1.1
# **  @param  $1  current version
# **  @return n/a
# *******************************************************************

update_format_from_1_0_to_1_1()
{
    echo "* Update database from version 1.0 to 1.1..."

    # create path if it does not exist
    mkdir -p "${EISMAN_PATH}/installed"

    sed -i -e 's#taken from /var/install#taken_from_/var/install/packages#1' \
       "${EISMAN_PATH}/installed.db"                                                    && \
    sed -i -e 's# #   #1' "${EISMAN_PATH}/installed.db"                                 && \
    sed -i -e 's# #   #1' "${EISMAN_PATH}/packages.db"                                  && \
    find "${EISMAN_PATH}/info" -name "*.rec" -exec sed -i -e 's# #   #1' {} \;          && \
    find "${EISMAN_PATH}/installed" -name "*.rec" -exec                                    \
        sed -i -e 's#taken from /var/install#taken_from_/var/install/packages#1' {} \;  && \
    find "${EISMAN_PATH}/installed" -name "*.rec" -exec sed -i -e 's# #   #1' {} \;

    if [ "$?" -eq "0" ]
    then
        echo "1.1" > "${EISMAN_PATH}/dbversion"

        mecho --ok
    else
        mecho --fail
        exit 1
    fi
}


# *******************************************************************
# **  perform format update from version 1.1 to 1.2
# **  @param  $1  current version
# **  @return n/a
# *******************************************************************

update_format_from_1_1_to_1_2()
{
    echo "* Update database from version 1.1 to 1.2..."

    # remove installed rec files directory, no longer needed
    if [ -d "${EISMAN_PATH}/installed" ]
    then
        rm -rf "${EISMAN_PATH}/installed"
    fi

    if [ "$?" -eq "0" ]
    then
        echo "1.2" > "${EISMAN_PATH}/dbversion"

        mecho --ok
    else
        mecho --fail
        exit 1
    fi
}


# *******************************************************************
# **  update database format. Stay in a loop and perform incremental
# **  updates until the database is in the correct format version
# **  @param  $1  current version
# **  @return n/a
# *******************************************************************

update_database_format()
{
    local version="${1}"

    while true
    do
        case "${version}" in
        "1.0")
            update_format_from_1_0_to_1_1
            ;;
        "1.1")
            update_format_from_1_1_to_1_2
            ;;
        "${EISMAN_DB_VERSION}")
            exit 0
            ;;
        *)
            echo "error: unknown database format \"${version}\"!" >&2
            exit 1
            ;;
        esac

        version=$(cat ${EISMAN_PATH}/dbversion)
    done
}


# *******************************************************************
# **  main script
# **  @param  n/a
# **  @return n/a
# *******************************************************************

main()
{
    while [ "${1:0:2}" = "--" ]
    do
        case $1 in
        --help)
            show_help
            exit 0
            ;;
        *)
            echo "error: unknown option \"$1\"!" >&2
            echo
            show_help
            exit 1
        esac
    done

    if [ "$#" -gt 0 ]
    then
        echo 'error: invalid number of arguments!' >&2
        echo
        show_help
        exit 1
    fi

    # make sure packages.db exists!
    touch "${EISMAN_PATH}/packages.db"

    # create info file paths
    mkdir -p "${EISMAN_PATH}/info"

    # check if database already exists
    if [ ! -f "${EISMAN_PATH}/installed.db" ] ||
       [ ! -f "${EISMAN_PATH}/dbversion" ]
    then
        if [ ! -f "${EISMAN_PATH}/dbversion" ]
        then
            # remove all info files if database doesn't exist
            rm -rf "${EISMAN_PATH}/info"
        else
            # get version from version file
            version=$(cat ${EISMAN_PATH}/dbversion)
            if [ "${version}" != "${EISMAN_DB_VERSION}" ]
            then
                rm -rf "${EISMAN_PATH}/info"
            fi
        fi

        # read files in packages and add them to the database
        update_record_files

        # write version to directory for later version checks
        echo "${EISMAN_DB_VERSION}" > "${EISMAN_PATH}/dbversion"
    else
        # get version from version file
        version=$(cat ${EISMAN_PATH}/dbversion)

        # check if version is valid
        if [ "${version}" = "${EISMAN_DB_VERSION}" ]
        then
            echo 'database is up to date!'
            exit 0
        else
            # convert database format
            update_database_format "${version}"
        fi
    fi
}

main "${@}"
