1# frozen_string_literal: true
2
3require "lazy_object"
4require "value_semantics/monkey_patched"
5
6require_relative "sim"
7
8class SIMRepo
9 value_semantics do
10 db Anything(), default: LazyObject.new { DB }
11 end
12
13 KEEPGO_HEADERS = {
14 "Accept" => "application/json",
15 "apiKey" => CONFIG[:keepgo][:api_key],
16 "accessToken" => CONFIG[:keepgo][:access_token]
17 }.freeze
18
19 def find(iccid)
20 req("line/#{iccid}/get_details").aget(head: KEEPGO_HEADERS).then { |req|
21 SIM.extract(JSON.parse(req.response)&.dig("sim_card"))
22 }
23 end
24
25 def refill(sim, **kwargs)
26 iccid = sim.is_a?(String) ? sim : sim.iccid
27
28 req("line/#{iccid}/refill").apost(
29 head: KEEPGO_HEADERS,
30 body: kwargs.to_json
31 ).then { |req| JSON.parse(req.response) }
32 end
33
34 def owned_by(customer)
35 customer = customer.customer_id if customer.respond_to?(:customer_id)
36 promise = db.query_defer(<<~SQL, [customer])
37 SELECT iccid, nickname FROM sims WHERE customer_id=$1
38 SQL
39 promise.then { |result|
40 EMPromise.all(result.map { |row|
41 find(row["iccid"]).then { |sim| sim.with(nickname: row["nickname"]) }
42 })
43 }
44 end
45
46 def put_owner(sim, customer, nickname=nil)
47 db.query_defer(<<~SQL, [customer.customer_id, sim.iccid, nickname])
48 UPDATE sims SET customer_id=$1, nickname=COALESCE($3, nickname) WHERE iccid=$2 AND customer_id IS NULL
49 SQL
50 end
51
52 def available
53 db.query_defer(<<~SQL).then { |r| find(r.first["iccid"]) }
54 SELECT iccid FROM sims WHERE customer_id IS NULL LIMIT 1
55 SQL
56 end
57
58protected
59
60 def req(path)
61 EM::HttpRequest.new(
62 "https://myaccount.keepgo.com/api/v2/#{path}",
63 tls: { verify_peer: true }
64 )
65 end
66end