#!/bin/bash
# @author 6543
# @version 0.1
# @date 2019-02-07

## Options/Parameter
# [$1]: <path to movie folder>

{ #set enviroemnt
    readonly TRUE=1      #like <stdbool.h>
    readonly FALSE=0     #like <stdbool.h>
    readonly TTSYNC_EXIST=0       #file exist local
    readonly TTSYNC_BACKUP=1      #file exist local - backup exist
    readonly TTSYNC_REMOTE=2      #file exists remote - not used jet
    readonly TTSYNC_DEL=3         #local file deleted
    readonly globalconf="/etc/tt/global"
}

{ #get options & args
    readonly mode=$(echo $1 | tr -d '-')
    moviedir="$1"
    [ -z "$moviedir" ] && [ -f "$globalconf" ] && {					# if (no argument) and (globalconf exist)
        if [ -z "$(grep "moviedir=" "$globalconf" )" ]; then			# and (moviedir is NOT in globalconf)
            echo 'neither "movie folder" is set in global config nor given as argument'
            exit 2
        else															# and (moviedir is in globalconf)
            moviedir="$(grep "moviedir=" "$globalconf" | cut -d '=' -f 2)"
        fi
    }
    [ -d "$moviedir" ] || { echo "moviedir \"$moviedir\" do not exist"; exit 3; } # check moviedir
    moviedir=""$(echo $moviedir | sed 's|/$||g')""
    [ -z "$moviedir" ] && exit 255 #catch case moviedir="/"
    readonly DATE=$(date '+%Y-%m-%d')
}

{ #db
    dbname="tt_test"
    dbhost="localhost"
    dbuser="root"
    dbpwd=""
}

function help() {
    #help menue
    echo "$0 is part of the TerabyteTerminator Project"
    echo ""
    echo "update-file-state [moviedir]"
    echo "  moviedir: Is optional if it is already in the global config"

    exit 0
}
[ "$mode" == "help" ] && help

###########################
## Programm Haupt Ablauf ##
###########################
function main() {
    #cd to moviedir
    cd "$moviedir"

    #db checks
    [ "$(db_check)" == $FALSE ] && exit 1

    #clean DB from old stuff
    {
        db_query "DELETE From File WHERE Size=0 OR MD5="" OR MD5 IS NULL;"
        #find dublicates !
    }

    #erselle zwei dateilisten
    list_tmp=$(mktemp -d)
    db_query "SELECT CONCAT('$moviedir/', Folder, '/', Name) FROM File WHERE TTSync=$TTSYNC_EXIST OR TTSync=$TTSYNC_BACKUP;" > "$list_tmp/indb"
    find "$moviedir" -type f > "$list_tmp/exist"

    #find new files
    grep -vf "$list_tmp/indb" "$list_tmp/exist" > "$list_tmp/new"

    #all IDs wich an old check date:
    db_query "SELECT ID FROM File Where TTCheck < '$DATE' OR TTCheck IS NULL;" | while read line; do
        #for each ID with an old check date ...
        ID=$line
        FILE=$(db_query "SELECT CONCAT('$moviedir/', Folder, '/', Name) FROM File WHERE ID=$ID;")
        if [ -f "$FILE" ]; then
            SIZE=$(db_query "SELECT Size FROM File WHERE ID=$ID;")
            SIZE_new="$(file_size "$FILE")"
            [ "$SIZE" != "$SIZE_new" ] && {
                echo "FILE CHANGE: $FILE"
                if [ "0" ==  "$SIZE_new" ]; then
                    #file exist but empty
                    #rm "$FILE" <- secure? 2check
                    db_query "UPDATE File SET TTSync=$TTSYNC_DEL,TTCheck='$DATE' WHERE ID=$ID;"
                else
                    #recalc md5 ... + check
                    #update DB
                    MD5_new=$(md5sum "$FILE" | cut -c -32)
                    MD5=$(db_query "SELECT MD5 FROM File WHERE ID=$ID;")

                    if [ "$MD5" == "$MD5_new" ]; then
                        db_query "UPDATE File SET Size=$SIZE_new,TTCheck='$DATE' WHERE ID=$ID;"
                    else
                        #new file/file changed!
                        db_query "UPDATE File SET TTSync=$TTSYNC_DEL,TTCheck='$DATE' WHERE ID=$ID;"
                        file_add "$(db_query "SELECT CONCAT(Folder, '/', Name) FROM File WHERE ID=$ID;")" "$MD5_new"
                    fi

                fi
            }
        else
            # file dont exist
            db_query "UPDATE File SET TTSync=$TTSYNC_DEL,TTCheck='$DATE' WHERE ID=$ID;"
        fi

    done

    #add new files ....
    cat "$list_tmp/new" | while read line; do
        file_add "$line"
    done


    rm -r "$list_tmp/"

}

###########################
## help functions #########
###########################

##check & prepair args
[ -z "$moviedir" ] && [ -f "$globalconf" ] && {					# if (no argument) and (globalconf exist)
    if [ -z "$(grep "moviedir=" "$globalconf" )" ]; then			# and (moviedir is NOT in globalconf)
        echo 'neither "movie folder" is set in global config nor given as argument'
        exit 2
    else															# and (moviedir is in globalconf)
        moviedir="$(grep "moviedir=" "$globalconf" | cut -d '=' -f 2)"
    fi
}
[ -d "$moviedir" ] || { echo "moviedir \"$moviedir\" do not exist"; exit 3; } # check moviedir
moviedir=""$(echo $moviedir | sed 's|/$||g')""
[ -z "$moviedir" ] && exit 255 #catch case moviedir="/"


# file_size <path> -> (du -b)/1024  [Kb]
function file_size() {
    if [ -f "$1" ]; then
        echo $(($(du -b "$1" | cut -f 1)/1024))
    else
        echo 0
    fi
}

# file_add [rel.path] (md5)
function file_add() {
    local MD5="$2"
    local relrevpath="$(echo "$1" | sed 's|^/||g' | sed 's|/$||g' | rev | sed "s/'/''/g")"   #last statement set ' as '' so it wont have an evect in the sql statement
    local name="$(echo "$relrevpath" | cut -d '/' -f 1 | rev)"
    local folder="$(echo "$relrevpath" | cut -d '/' -f 2- | rev)"
    local FILE="$moviedir/$(echo "$relrevpath" | rev)"
    [ -f "$FILE" ] || {
        echo "ERROR: file_add: file not exist: $FILE"
        return 1
    }
    [ -z "$MD5" ] && MD5="$(md5sum "$FILE" | cut -c -32)"
    local SIZE="$(file_size "$FILE")"

    #check if already exist
    IDs=($(db_query "SELECT ID FROM File WHERE Name='$name' AND Folder='$folder';"))
    #wenn einmal existiert ...
    if [ "${#IDs[@]}" -gt 0 ]; then
        # undelet files ...
        local IDs_undel="$(db_query "SELECT ID FROM File WHERE AND TTSync='$TTSYNC_DEL' AND MD5='$MD5' AND Name='$name' AND Folder='$folder';")"
        db_query "UPDATE File SET TTSync=$TTSYNC_EXIST,TTCheck='$DATE',Size='$SIZE' WHERE AND TTSync='$TTSYNC_DEL' AND MD5='$MD5' AND Name='$name' AND Folder='$folder';"

        #same path wrong md5
        #local IDs_W5="$(db_query "SELECT ID FROM File WHERE TTSync!='$TTSYNC_REMOTE' AND MD5!='$MD5' AND Name='$name' AND Folder='$folder';")"
        db_query "UPDATE File SET TTSync=$TTSYNC_DEL,TTCheck='$DATE' WHERE TTSync!='$TTSYNC_REMOTE' AND MD5!='$MD5' AND Name='$name' AND Folder='$folder';"

        #if something MVs ...
        local IDs_mv="$(db_query "SELECT ID FROM File WHERE AND MD5='$MD5' AND Size='$SIZE' AND Name!='$name' AND Folder!='$folder';")"
        db_query "UPDATE File SET TTCheck='$DATE',Name='$name',Folder='$folder',TTSync='$TTSYNC_EXIST' WHERE AND MD5='$MD5' AND Size='$SIZE' AND Name!='$name' AND Folder!='$folder';"

        #wenn gelöschte wiederhergestellt oder verschobene dateien entdekt... -> func done

    else
        db_query "INSERT INTO File (Name,Folder,MD5,Size,TTSync,TTCheck) VALUES ('$name','$folder','$MD5','$SIZE',$TTSYNC_EXIST,'$DATE');"
    fi

    #db path exist && ttsync=exist/backup && md5 !same -> ttsync=del + new db entry
    #or new db entry

    #db entry is{
    # chek if size ->md5 exist -> update path&name (MV)
    # else complete new entry
    #}
}


# db_query <query> -> result
function db_query() {
    local args="-sN"  #no headers, no grid
    args+=" -h$dbhost"
    args+=" -u$dbuser"
    [ -n "$dbpwd" ] && args+=" -p$dbpwd"
    args+=" $dbname"
    echo $@ | mysql $args
}

function db_check()  {
    echo DUMMY FUNC db_check
    echo aim: check DB conection + shema
    echo $TRUE
}

# db_F-ID_getPath <F-ID> -> <Path>
function db_id_getPath() {
    db_query "SELECT CONCAT('$moviedir/', Folder, '/', Name) FROM File WHERE ID=$1;"
}



main #aufruf der main function (eig. programmstart)
