1# frozen_string_literal: true
 2
 3require "cbor"
 4require "json"
 5
 6require_relative "geo_code"
 7
 8class GeoCodeRepo
 9	def initialize(memcache: MEMCACHE)
10		@memcache = memcache
11	end
12
13	def find(q)
14		cache(q) {
15			EM::HttpRequest.new(
16				"https://geocoder.ca/",
17				tls: { verify_peer: true }
18			).aget(query: { json: 1, locate: q }).then { |res|
19				json = JSON.parse(res.response)
20				raise "Geocode Failure" unless json["latt"] && json["longt"]
21
22				json
23			}
24		}.then(&GeoCode.method(:for))
25	end
26
27protected
28
29	def cache(k, &blk)
30		k = "geocode_#{k.gsub(/ /, '%20')}"
31		promise = EMPromise.new
32		@memcache.get(k, &promise.method(:fulfill))
33		promise.then { |cbor|
34			CBOR.decode(cbor)
35		}.catch(&blk).then { |result|
36			@memcache.set(k, result.to_cbor)
37			result
38		}
39	end
40end