#!/bin/sh
# this script downloads map tiles requested by aprsmap
# the 1st command line parameter must always be present and be "-r"
# the 2nd command line parameter must specify a map tile root directory path
# the 3rd command line parameter is optional and specifies an alternate maplist file
# e.g.: gm.sh -r map_tile_root_directory [maplist_file]
#
# requested map tiles are contained in a file generated by aprsmap with the format:
# mapname z x y
#
# mapname is looked up in the maplist file and the corresponding tile server
# is then used to download the map tile defined by {z}, {x} and {y}
# the downloaded map tiles are stored under the specified map tile root directory
#
# this script is selected by using the aprsmap.cfg entry:
# Get Map Program|1|gm.sh
#
# the map_tile_root_directory is specified using the aprsmap.cfg entry:
# Map Directory Path||<path>

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

# file created by aprsmap of a list of map tiles to fetch
ORIGFN="gettiles"

# default filename for list of available maps
MAPFN="maplist"

# sample commands to retrieve map tiles showing wget and curl usage
# blank user-agent, quiet mode, 5 sec timeout, 1 retry, output file follows
GETCMDBASE="wget -U \"\" -q -T 5 -t 1 -O"
#GETCMDBASE="wget2 -U \"\" -q -T 5 -t 1 -O"
#GETCMDBASE="curl -A \"\" -s -S -m 5 -o"

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

# if root map directory path specified by aprsmap
if [ "-r" = $1 ] ; then
    MAPDIR=$2
else
# assume missing map root directory
# aprsmap is attempting to store and retrieve maps at starting at / path
# this can occur if the "Map Directory Path" in aprsmap.cfg is blank
    echo "Missing \"Map Directory Path\" in aprsmap.cfg"
    exit 1
fi

# use user-specified maplist if passed via command line, else use default
if [ -z $3 ] ; then
    MAPLIST=$MAPFN
else
    MAPLIST=$3
fi

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

# move the original file to a temporary file to prevent a race condition where
# aprsmap seems to attempt to continue writing to the original file before
# this script completes processing
FN=$(mktemp)
#mv $ORIGFN $FN
cp $ORIGFN $FN

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

# if the tiles directory does not exist then attempt to create one
if ! [ -d $MAPDIR ] ; then
    mkdir $MAPDIR
fi

# if tiles directory exists and the tile list is accessible
if [ -d $MAPDIR ] ; then
    if [ -r $FN ] ; then
# create the rest of the map tile directory structure if necessary
        while read mapname mapz mapx mapy ; do
            if ! [ -d $MAPDIR/$mapname ] ; then
                mkdir $MAPDIR/$mapname
            fi
            if ! [ -d $MAPDIR/$mapname/$mapz ] ; then
                mkdir $MAPDIR/$mapname/$mapz
            fi
            if ! [ -d $MAPDIR/$mapname/$mapz/$mapx ] ; then
                mkdir $MAPDIR/$mapname/$mapz/$mapx
            fi

# try to match the requested map name with a server in the map list file
            if [ -r $MAPLIST ] ; then
                while read tileid tileorder tileformat tileurl tileapikey tilecomment ; do
                    if [ "$tileid" = "$mapname" ] ; then
                        ORDER=$tileorder
                        EXTENT=$tileformat
                        SERVER=$tileurl
# if an api key or access token is present
                        if ! [ -z $tileapikey ] ; then
                            if [ $(echo $tileapikey | cut -c1-8) = "?apikey=" ] ||
                               [ $(echo $tileapikey | cut -c1-14) = "?access_token=" ] ; then
                                APIKEY=$tileapikey
                            fi
                        fi
                        break;
                    fi
                done < $MAPLIST
                if [ -z $SERVER ] ; then
                    echo "Unable to find map named \"$mapname\" in map file: $MAPLIST"
                    rm -f $FN
                    exit 1;
                fi
            else
                echo "Unable to access map file: $MAPLIST"
                rm -f $FN
                exit 1
            fi

# tile server coordinate ordering may be different from what aprsmap expects
# always store locally as "zxy" regardless of remote tile ordering
            MAPFILE=$mapz/$mapx/$mapy.$EXTENT
            if [ "zxy" = $ORDER ] ; then
                GETTILE=$MAPFILE
            elif [ "zyx" = $ORDER ] ; then
                GETTILE=$mapz/$mapy/$mapx.$EXTENT
            else
                echo "Unexpected tile server coordinate ordering"
                rm -f $FN
                exit 1
            fi

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

# so far so good, initiate retrieval of the tile
            echo "Loading tile: $MAPFILE ..."
            echo -n "-> from $SERVER - "
            $GETCMDBASE $MAPDIR/$mapname/$MAPFILE $SERVER/$GETTILE$APIKEY &
            echo "initiated download."
        done < $FN
        rm -f $FN
    else
        echo "Unable to access tiles file: $FN"
        exit 1
    fi
else
    echo "Directory $MAPDIR not found."
    exit 1
fi

exit 0
