#!/bin/bash

DEFAULT_OUTPUT_FOLDER=outputs

DEFAULT_WRITER=insa2018

if [ -z "${DEFAULT_THREADS}" ]; then
    DEFAULT_THREADS=2
fi

if [ -z "${DEFAULT_MEMORY_MODE}" ]; then
    DEFAULT_MEMORY_MODE=hd
fi

bounding_box=
bounding_poly=
map_id=
map_name=
debug=false

graph_only=false
mapsforge_only=false

input_file=
output_file=

# FUNCTION help_short()
#
# Print short usage information.
function help_short() {
    echo "Usage: $0 [-h|--help] [-d|--debug] [-i|--id MAP_ID] [-n|--name MAP_NAME] [-b|--bounding-box FILE|BBOX] [-g|--graph-only] [-f|--mapsforge-only] [-p|--bounding-polygon FILE] [-o|--output OUTPUT_NAME] INPUT_FILE"
}

# FUNCTION help_long()
#
# Print detailed usage information.
function help_long() {
    help_short
    printf "\t-d,--debug\tEnable debug mode.\n"
    printf "\t-i,--id\tMap ID.\n"
    printf "\t-n,--name\tMap name.\n"
    printf "\t--graph-only\tDo not generate Mapsforge file.\n"
    printf "\t--mapsforge-only\tDo not generate graph file.\n"
    printf "\t-b,--bounding-box\tSpecify a bounding-box, either via a string or a file.\n"
    printf "\t-p,--bounding-polygon\tSpecify a bounding-polygon, only used for OSM2Graph.\n"
    printf "\t-h,--help\tPrint this help.\n"
}

# FUNCTION error(...)
#
# Print error composed of arguments, then exit.
function error() {
    echo "ERROR: $0: $*" >> /dev/stderr
    exit 1
}

# FUNCTION error_and_usage(...)
#
# Print error composed of arguments, followed by help, then exit.
function error_and_usage() {
    echo "ERROR: $0: $*" >> /dev/stderr
    help_short
    exit 1
}

# FUNCTION warning(...)
#
# Print warning / information composed of arguments.
function warning() {
    echo "WARNING: $0: $*" >> /dev/stderr
}


# FUNCTION warning(...)
#
# Print information composed of arguments.
function info() {
    echo "INFO: $0: $*" >> /dev/stderr
}


# FUNCTION run(...)
#
# Execute given command if debug mode is disabled, otherwize
# print it to stderr.
function run() {
    $debug && warning $*
    $debug || $*
}

# FUNCTION check_input_file()
#
# Check if input file exists and has read access.
function check_input_file() {

    if [ -z "${input_file}" ]; then
        error_and_usage "Missing input file."
    fi

    if [ ! -e "${input_file}" ]; then
        error "${input_file} does not exist."
    fi

    if [ ! -e "${input_file}" ]; then
        error "${input_file} does not exist."
    fi

    if [ ! -r "${input_file}" ]; then
        error "${input_file} is not readable."
    fi

}

# FUNCTION check_output_file()
#
# Check output file.
function check_output_file() {

    if [ -z "${output_file}" ]; then
        output_file=${DEFAULT_OUTPUT_FOLDER}/$(basename -s .pbf ${input_file})
        info "No output file specific, switching to ${output_file}."
    fi

}

# Loop for command line arguments, see:
#   http://stackoverflow.com/a/14203146/2666289
while [ ! -z "$1" ]
do
    key="$1"

    case $key in
        -b|--bounding-box)
            bounding_box="$2"
            shift
            ;;
        -p|--bounding-polygon)
            bounding_poly="$2"
            shift
            ;;
        -f|--mapsforge-only)
            mapsforge_only=true
            ;;
        -g|--graph-only)
            graph_only=true
            ;;
        -i|--id)
            map_id="$2"
            shift
            ;;
        -n|--name)
            map_name="$2"
            shift
            ;;
        -d|--debug)
            debug=true
            ;;
        -o|--output)
            output_file="$2"
            shift
            ;;
        -h|--help)
            help_long
            exit 0
            ;;
        *)
            input_file="$key"
            ;;
    esac
    shift # past argument or value
done

check_input_file
check_output_file

if [ ! $mapsforge_only ] && [ -z "${map_id}" ]; then
    error_and_usage "No map ID specified."
fi

if [ ! $mapsforge_only ] && [ -z "${map_name}" ]; then
    error_and_usage "No map name specified."
fi

if [ ! -z "${bounding_box}" ] && [ -e "${bounding_box}" ]; then
    bounding_box=$(cat ${bounding_box})
fi

if [ -z "${bounding_box}" ] && echo ${input_file} | grep "merge"; then
    error_and_usage "Using a merged file (_merge) without bounding box is not possible."
fi

mkdir -p $(dirname ${output_file})

# Uncomment this or set the variable before starting the script if
# you want to generate file for huge map (change 26g to whatever is
# relevant for your system)
# export JAVACMD_OPTIONS="-Xms26g -Xmx26g"

if ${graph_only}; then
    info "Skipping mapsforge generation... "
else
    CMD_MF="bin/osmosis --rb ${input_file} --lp --mapfile-writer file=${output_file}.mapfg type=${DEFAULT_MEMORY_MODE} threads=${DEFAULT_THREADS}"

    if [ ! -z "${bounding_box}" ]; then
        CMD_MF="${CMD_MF} bbox=${bounding_box}"
    fi

    echo ${CMD_MF}
    ${CMD_MF}

fi

if ${mapsforge_only}; then
    info "Skipping graph generation... "
else

    # Merge file as input...
    if echo ${input_file} | grep "merge"; then

        # Try to find the originl (.osm.pbf)...
        input_file=$(echo ${input_file} | sed 's/_merge.pbf/.osm.pbf/')

        # ...or a generated .pbf...
        if [ ! -e ${input_file} ]; then
            input_file=$(echo ${input_file} | sed 's/.osm//')
        fi

        # If nothing is found, warn the user...
        if [ ! -e ${input_file} ]; then
            warning "Merge file specified but the original file was not found, the graph file may not be generated correctly from the merged file."
        else
            info "Merge file detected, original file was found: ${input_file}."
        fi
    fi

    CMD_GR="bin/osmosis --rb ${input_file} --lp"

    if [ ! -z "${bounding_poly}" ]; then
        CMD_GR="${CMD_GR} --bounding-polygon file=${bounding_poly} completeWays=yes --lp"
    else
        if [ ! -z "${bounding_box}" ]; then
            osmbbox=$(echo ${bounding_box} | \
                             tr "," " " | \
                             xargs printf "bottom=%f left=%f top=%f right=%f")
            CMD_GR="${CMD_GR} --bounding-box ${osmbbox} completeWays=yes --lp"
        fi
    fi

    CMD_GR="${CMD_GR} --tf reject-relations --lp"
    CMD_GR="${CMD_GR} --tf accept-ways highway=$(cat plugins/OSM2Graph/resources/highway-filter.cmd) natural=coastline junction=roundabout --lp"
    CMD_GR="${CMD_GR} --used-node --lp --osm2graph writer=${DEFAULT_WRITER} file=${output_file}.mapgr threads=${DEFAULT_THREADS}"

    echo ${CMD_GR} id="${map_id}" name="${map_name}"
    ${CMD_GR} id="${map_id}" name="${map_name}"
fi
