#!/usr/bin/env bash
# WordPress test environment installer.
#
# Canonical script (from WP-CLI scaffold-test) adapted for this plugin.
# Downloads WordPress core + the test framework, creates the test
# database, and writes wp-tests-config.php.
#
# Usage:
#   bin/install-wp-tests.sh <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]

set -euo pipefail

if [ $# -lt 3 ]; then
    echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
    exit 1
fi

DB_NAME="$1"
DB_USER="$2"
DB_PASS="$3"
DB_HOST="${4-127.0.0.1}"
WP_VERSION="${5-latest}"
SKIP_DB_CREATE="${6-false}"

TMPDIR="${TMPDIR-/tmp}"
TMPDIR="${TMPDIR%/}"
WP_TESTS_DIR="${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}"
WP_CORE_DIR="${WP_CORE_DIR-$TMPDIR/wordpress/}"

download() {
    if command -v curl >/dev/null; then
        curl -fsSL -o "$2" "$1"
    elif command -v wget >/dev/null; then
        wget -nv -O "$2" "$1"
    else
        echo "error: neither curl nor wget available" >&2
        exit 1
    fi
}

if [[ "$WP_VERSION" =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then
    WP_BRANCH=$(echo "$WP_VERSION" | grep -oE '^[0-9]+\.[0-9]+')
    WP_TESTS_TAG="branches/$WP_BRANCH"
elif [[ "$WP_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
    WP_TESTS_TAG="branches/$WP_VERSION"
elif [[ "$WP_VERSION" =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
    if [[ "$WP_VERSION" =~ [0-9]+\.[0-9]+\.[0] ]]; then
        WP_TESTS_TAG="tags/$(echo "$WP_VERSION" | grep -oE '^[0-9]+\.[0-9]+')"
    else
        WP_TESTS_TAG="tags/$WP_VERSION"
    fi
elif [[ "$WP_VERSION" == "nightly" || "$WP_VERSION" == "trunk" ]]; then
    WP_TESTS_TAG="trunk"
else
    download http://api.wordpress.org/core/version-check/1.7/ "$TMPDIR/wp-latest.json"
    LATEST_VERSION=$(grep -o '"version":"[^"]*' "$TMPDIR/wp-latest.json" | sed 's/"version":"//' | head -1)
    if [[ -z "$LATEST_VERSION" ]]; then
        echo "Latest WordPress version could not be found"
        exit 1
    fi
    WP_TESTS_TAG="tags/$LATEST_VERSION"
fi

install_wp() {
    if [ -d "$WP_CORE_DIR" ]; then
        return
    fi
    mkdir -p "$WP_CORE_DIR"

    if [[ "$WP_VERSION" == "nightly" || "$WP_VERSION" == "trunk" ]]; then
        mkdir -p "$TMPDIR/wordpress-nightly"
        download https://wordpress.org/nightly-builds/wordpress-latest.zip "$TMPDIR/wordpress-nightly/wordpress-nightly.zip"
        unzip -q "$TMPDIR/wordpress-nightly/wordpress-nightly.zip" -d "$TMPDIR/wordpress-nightly/"
        mv "$TMPDIR/wordpress-nightly/wordpress/"* "$WP_CORE_DIR"
    else
        if [ "$WP_VERSION" == "latest" ]; then
            local ARCHIVE_NAME='latest'
        elif [[ "$WP_VERSION" =~ [0-9]+\.[0-9]+ ]]; then
            download http://api.wordpress.org/core/version-check/1.7/ "$TMPDIR/wp-latest.json"
            if [[ "$WP_VERSION" =~ [0-9]+\.[0-9]+\.[0] ]]; then
                LATEST_VERSION=$(echo "$WP_VERSION" | grep -oE '^[0-9]+\.[0-9]+')
            else
                LATEST_VERSION="$WP_VERSION"
            fi
            local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
        else
            local ARCHIVE_NAME="wordpress-$WP_VERSION"
        fi
        download "https://wordpress.org/${ARCHIVE_NAME}.tar.gz" "$TMPDIR/wordpress.tar.gz"
        tar --strip-components=1 -zxmf "$TMPDIR/wordpress.tar.gz" -C "$WP_CORE_DIR"
    fi

    download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php "$WP_CORE_DIR/wp-content/db.php"
}

install_test_suite() {
    if [ ! -d "$WP_TESTS_DIR" ]; then
        mkdir -p "$WP_TESTS_DIR"
        svn co --quiet "https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/" "$WP_TESTS_DIR/includes"
        svn co --quiet "https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/" "$WP_TESTS_DIR/data"
    fi

    if [ ! -f "$WP_TESTS_DIR/wp-tests-config.php" ]; then
        download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR/wp-tests-config.php"
        WP_CORE_DIR=$(echo "$WP_CORE_DIR" | sed "s:/\+$::")
        sed -i.bak "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR/wp-tests-config.php"
        sed -i.bak "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR/wp-tests-config.php"
        sed -i.bak "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR/wp-tests-config.php"
        sed -i.bak "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR/wp-tests-config.php"
        sed -i.bak "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR/wp-tests-config.php"
        rm -f "$WP_TESTS_DIR/wp-tests-config.php.bak"
    fi
}

recreate_db() {
    shopt -s nocasematch
    if [[ "$1" =~ ^(y|yes)$ ]]; then
        mysqladmin drop -f "$DB_NAME" --user="$DB_USER" --password="$DB_PASS"${DB_HOSTNAME:+ --host="$DB_HOSTNAME"} --protocol=tcp
        create_db
        echo "Recreated the database ($DB_NAME)."
    else
        echo "Leaving the existing database ($DB_NAME) in place."
    fi
    shopt -u nocasematch
}

create_db() {
    mysqladmin create "$DB_NAME" --user="$DB_USER" --password="$DB_PASS"${DB_HOSTNAME:+ --host="$DB_HOSTNAME"} --protocol=tcp
}

install_db() {
    if [ "${SKIP_DB_CREATE}" = "true" ]; then
        return 0
    fi

    DB_HOSTNAME="$(echo "$DB_HOST" | sed -e 's|:.*||')"
    DB_SOCK_OR_PORT="$(echo "$DB_HOST" | sed -e 's|^[^:]*||')"
    DB_EXTRA=""
    if [ -n "$DB_HOSTNAME" ] ; then
        if [ "$(echo "$DB_SOCK_OR_PORT" | grep -e '^:[0-9]\{1,\}$')" ]; then
            DB_EXTRA=" --host=$DB_HOSTNAME --port=$(echo "$DB_SOCK_OR_PORT" | tr -d :) --protocol=tcp"
        elif [ -n "$DB_SOCK_OR_PORT" ] ; then
            DB_EXTRA=" --socket=${DB_SOCK_OR_PORT/#:/}"
        elif [ -n "$DB_HOSTNAME" ] ; then
            DB_EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
        fi
    fi

    if [ "$(mysql --user="$DB_USER" --password="$DB_PASS"$DB_EXTRA --execute='show databases;' | grep ^"$DB_NAME"$)" ]; then
        recreate_db "$RECREATE_DB"
    else
        create_db
    fi
}

install_wp
install_test_suite
install_db
