#!/bin/sh

. /lib/functions.sh
. /lib/netifd/netifd-proto.sh
. /usr/share/libubox/jshn.sh

get_tower_ids() {
    device=$(uci get geolocationd.geolocation.device)
    [ -z $device ] && {
    device=/dev/ttyUSB2
    uci set geolocationd.geolocation.device="/dev/ttyUSB2"
    }

    #4G modem
    [ -e "$device" ] || return 1
    uci set geolocationd.geolocation.api=opencellid

    #modem
    api=opencellid
    #huawei
    (lsusb | grep 12d1 > /dev/null) && {
    gcomcmd=getlocation_huawei_$api.gcom
    }
    #quectel
    (lsusb | grep 2c7c > /dev/null) && {
    gcomcmd=getlocation_quectel_$api.gcom
    }
    #simcom
    (lsusb | grep 1e0e > /dev/null) && {
    gcomcmd=getlocation_simcom_$api.gcom
    }
    killall-9  gcom 
    gcom -d $device -s /etc/gcom/$gcomcmd > /tmp/cellid
    return $?
}

get_latitude_and_longitude_by_opencellid() {
    data=$(cat /tmp/cellid)
    token=$(uci get geolocationd.geolocation.opencellidtoken)
    curl -k --request POST \
      --url https://us1.unwiredlabs.com/v2/process.php \
      --data "{\"token\": \"$token\", $data}" > /tmp/opencellid
    opencellid=$(cat /tmp/opencellid)
    json_load "$opencellid"
    json_get_var olat lat
    json_get_var olon lon
    [ -z "$olat" ] && {
        return 1
    }
    [ -z "$olon" ] && {
        return 1
    }
    uci set geolocationd.geolocation.latitude=$olat
    uci set geolocationd.geolocation.longitude=$olon
    #echo "lat $olat lon $olon"
    uci commit geolocationd
    return 0
}

get_openstreetmap_info_from_lat_and_lon() {

    lat=$(uci get geolocationd.geolocation.latitude)
    lon=$(uci get geolocationd.geolocation.longitude)
    #echo "lat $lat lon $lon"
    openstreetmap=$(curl -k "https://nominatim.openstreetmap.org/reverse?lat=$lat&lon=$lon&format=json&accept-language=en")
    echo $openstreetmap > /tmp/openstreetmap
    json_load "$openstreetmap"
    #echo "$openstreetmap"
    json_select address
    json_get_var place place
    street=$(echo $place | tr -d ' ')
    #echo "street $street"
    [ -z "$street" ] && {
    json_get_var road road
    json_get_var building building
    street=$(echo $road$building | tr -d ' ')
    }
    #echo "street $street"
    uci set geolocationd.geolocation.street=$street
    json_get_var quarter quarter
    uci set geolocationd.geolocation.quarter=$quarter
    json_get_var suburb suburb
    uci set geolocationd.geolocation.suburb=$suburb
    json_get_var town town
    uci set geolocationd.geolocation.town=$town
    json_get_var city city
    uci set geolocationd.geolocation.city=$city
    json_get_var county county
    county=$(echo $county | tr -d ' ')
    uci set geolocationd.geolocation.county=$county
    json_get_var province province
    uci set geolocationd.geolocation.province=$province
    json_get_var state state
    uci set geolocationd.geolocation.state=$state
    json_get_var country country
    uci set geolocationd.geolocation.country=$country
    #json_get_var iso ISO3166-2-lvl6
    #iso3166=${iso:0:2}
    #uci set geolocationd.geolocation.iso3166=$iso3166
    uci commit geolocationd
}

get_location_from_tower() {

    get_tower_ids && {
        get_latitude_and_longitude_by_opencellid && {
            get_openstreetmap_info_from_lat_and_lon
        }
    }
}

get_location_from_ip() {

    #there is not 4G,wifi -> country
    country=$(curl ipinfo.io/country)
    echo "$country" > /tmp/ipinfo.io
    uci set geolocationd.geolocation.country=$country
    uci commit geolocationd
}

get_json_geolocation() {

    sn=$(hostname)
    # return json object or an array
    json_init
    lat=$(uci get geolocationd.geolocation.latitude)
    [ -z "$lat" ] || json_add_double 'lat' $lat
    lon=$(uci get geolocationd.geolocation.longitude)
    [ -z "$lon" ] || json_add_double 'lon' $lon
    street=$(uci get geolocationd.geolocation.street)
    [ -z "$street" ] || json_add_string 'street' $street
    quarter=$(uci gset geolocationd.geolocation.quarter)
    [ -z "$quarter" ] || json_add_string 'quarter' $quarter
    suburb=$(uci get geolocationd.geolocation.suburb)
    [ -z "$suburb" ] || json_add_string 'suburb' $suburb
    town=$(uci get geolocationd.geolocation.town)
    [ -z "$town" ] || json_add_string 'town' $town
    city=$(uci get geolocationd.geolocation.city)
    [ -z "$city" ] || json_add_string 'city' $city
    county=$(uci get geolocationd.geolocation.county)
    [ -z "$county" ] || json_add_string 'county' $county
    province=$(uci get geolocationd.geolocation.province)
    [ -z "$province" ] || json_add_string 'province' $province
    state=$(uci get geolocationd.geolocation.state)
    [ -z "$state" ] || json_add_string 'state' $state
    country=$(uci get geolocationd.geolocation.country)
    [ -z "$country" ] || json_add_string 'country' $country

    #default values
    [ -z "$lat" ] && {
        lat=42.817293
        json_add_double 'lat' $lat
    }
    [ -z "$lon" ] && {
        lon=-1.601258
        json_add_double 'lon' $lon
    }
    [ -z "$country" ] && {
        country=ES
        json_add_string 'country' $country
    }

    json_add_string 'from' $sn
    json_close_object

    #json object
    json=$(json_dump)
    echo "$json"
}

publish_geolocation() {
	json=$(get_json_geolocation)
	#echo "json $json"
        ubus send 6geolocation "$json"
}


case "$1" in
	list)
		echo '{ "update": { }, "info": { }, "set": { } }'
	;;
	call)
		case "$2" in
			update)
				#get location
                                get_location_from_tower && {
                                    # answer location
                                    get_json_geolocation
                                    # publish geolocation
                                    publish_geolocation
                                    return
                                }
                                country=$(uci get geolocationd.geolocation.country)
                                #filter: geo slaves & by set
                                [ -z $country ] && get_location_from_ip
                                # answer location
                                get_json_geolocation
			;;
			info)
                                # answer location
                                get_json_geolocation
			;;
			set)
				read input;                         
                        	json init
				json_load "$input"
				#json_select geolocation
				json_get_var lati lat
				json_get_var long lon
				json_get_var con country
                                ucilat=$(uci get geolocationd.geolocation.latitude)
                                ucilon=$(uci get geolocationd.geolocation.longitude)
                                ucicountry=$(uci get geolocationd.geolocation.country)
                                # check new values
				[ "$lati" == "$ucilat" ] && [ "$long" == "$ucilon" ] && [ "$con" == "$ucicountry" ] && {
                                	# answer location
                                	get_json_geolocation
                                    return
				}
                                # save new values
                                uci set geolocationd.geolocation.latitude=$lati
                                uci set geolocationd.geolocation.longitude=$long
                                uci set geolocationd.geolocation.country=$con
				uci commit geolocationd
				
                                # use case: lat&long without country
				[ -z "$con" ] && {
					get_openstreetmap_info_from_lat_and_lon
				}
                                # answer location
                                get_json_geolocation
				# publish geolocation
				publish_geolocation
                        ;;
		esac
	;;
esac


