#!/bin/bash

### error_handling

function trap_error() {
    error_code=$1
    error_line=$2

    if [[ ${error_code} -lt 100 ]]; then
        printf "\nEXIT #${error_code} due to error at line ${error_line} : \n-----------------------------------------\n"
        sed "${error_line}q;d" $0
        echo
    fi
    exit $error_code
}
set -e
trap 'trap_error $? $LINENO' ERR

### ------------------

function detectWordpress() {
    local result=$(pwd)
    while [[ ! ("$result" == / || -f "$result/wp-config.php") ]]; do
        result=$(dirname "$result")
    done

    if [[ "$result" == / ]]; then
        echo >&2 "no WORDPRESS detected!"
        exit 100
    fi

    echo "$result"
}

function getConfigComment() {
    local result=$(grep -e "^#" $WP_CONFIG | grep "$1" | head -n1 | cut -d ',' -f2 | cut -d \' -f2)
    if [[ -z "$result" ]]; then
        echo "config comment: $1 not found!"
        exit 2
    fi
    echo "$result"
}
function getConfigEntry() {
    local result=$(grep "$1" $WP_CONFIG | head -n1 | cut -d ',' -f2 | cut -d \' -f2)
    if [[ -z "$result" ]]; then
        echo "config entry: $1 not found!"
        exit 2
    fi
    echo "$result"
}

function sql() {
    local result=$(echo "$1" | mysql -srN -u $DB_USER -h $DB_HOST $DB_NAME -p$DB_PASS 2>&1)
    if [[ $result =~ ^ERROR ]]; then
        echo >&2 "sql failure: $result"
        exit 3
    else
        echo "$result"
    fi
}

function sqlFile() {
    local result=$(cat "$1" | mysql -srN -u $DB_USER -h $DB_HOST $DB_NAME -p$DB_PASS 2>&1)
    if [[ $result =~ ^ERROR ]]; then
        echo >&2 "sql failure: $result"
        exit 3
    else
        echo "$result"
    fi
}
function changeHome() {
    local FROM=$1
    local TO=$2
    sql "UPDATE wp_options SET option_value = replace(option_value, '$FROM', '$TO') WHERE option_name = 'home' OR option_name = 'siteurl'"
    sql "UPDATE wp_posts SET guid = replace(guid, '$FROM','$TO')"
    sql "UPDATE wp_posts SET post_content = replace(post_content, '$FROM', '$TO')"
    sql "UPDATE wp_postmeta SET meta_value = replace(meta_value,'$FROM','$TO')"
}

function lastMigration() {
    sql "SELECT migration_file FROM migrations ORDER BY last_run DESC LIMIT 1"
}

function upgradeMigration() {
    local LAST_MIGRATION=$1
    local UPGRADE=false
    if [[ "$LAST_MIGRATION" == '' ]]; then
        UPGRADE=true
    fi

    local MIG_BASE="$WP_BASE/wp-content/migrations"
    local MIGRATIONS=$(ls -p1 $MIG_BASE | grep -v /)
    local MIG_FILE
    for mig in $MIGRATIONS; do
        if [[ "$UPGRADE" == true ]]; then
            printf "applying %50s ... " $mig
            printf "%d %d" $(sqlFile $MIG_BASE/$mig)
            echo " DONE"
            MIG_FILE=$mig
        else
            printf "useless %50s \n" $mig
            if [[ "$LAST_MIGRATION" == "$mig" ]]; then
                UPGRADE=true
            fi
        fi
    done

    if [[ $UPGRADE == true && $MIG_FILE != '' ]]; then
        local done=$(sql "INSERT INTO migrations(migration_file, last_run) VALUES ('$mig', NOW())")
        echo "all migrations succeeded, wrote: $mig"
    else
        echo "already up-to-date"
    fi
}

function buildMigrations() {
    if [[ ! -d "$WP_BASE"/wp-content/migrations ]]; then
        mkdir -p "$WP_BASE"/wp-content/migrations
        echo "migrations folder created!"
    fi

    sql "CREATE TABLE IF NOT EXISTS migrations (id int(11) NOT NULL AUTO_INCREMENT, migration_file varchar(255) COLLATE utf8_unicode_ci NOT NULL, last_run varchar(45) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (id) )"

}

function playEnvironment() {

    buildMigrations

    local PLATFORM=$1
    local PLATFORM_BASE="$WP_BASE/wp-content/migrations/$PLATFORM"
    if [[ -d "$PLATFORM_BASE" ]]; then
        echo play platform $PLATFORM

        local MIGRATIONS=$(ls -p1 $PLATFORM_BASE | grep -v /)
        for mig in $MIGRATIONS; do
            printf "applying %50s ... " $mig
            printf "%d %d" $(sqlFile $PLATFORM_BASE/$mig)
            echo " DONE"
        done
    fi
}

## MAIN
## ----

WP_BASE=$(detectWordpress)
WP_CONFIG="$WP_BASE/wp-config.php"
echo "WP_BASE = $WP_BASE"

WP_HOME=$(getConfigComment WP_HOME)
echo "WP_HOME = $WP_HOME"

DB_HOST=$(getConfigEntry DB_HOST)
DB_NAME=$(getConfigEntry DB_NAME)
DB_USER=$(getConfigEntry DB_USER)
DB_PASS=$(getConfigEntry DB_PASSWORD)

CURRENT_HOME=$(sql "SELECT option_value FROM wp_options WHERE option_name = 'home'")
if [[ "$CURRENT_HOME" != "$WP_HOME" ]]; then
    echo "HOME detected = $CURRENT_HOME , needs to apply changes"
    $(changeHome "$CURRENT_HOME" "$WP_HOME")
fi

if [[ "$WP_HOME" =~ https?:\/\/beta[0-9]*\..*|https?:\/\/.*\.beta[0-9]*\..* ]]; then
    playEnvironment BETA
else
    if [[ "$WP_HOME" =~ https?:\/\/dev[0-9]*\..*|https?:\/\/.*\.dev[0-9]*\..* ]]; then
        playEnvironment DEV
    else
        playEnvironment PROD
    fi
fi

CURRENT_MIGRATION=$(lastMigration)
upgradeMigration "$CURRENT_MIGRATION"