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 EM::HttpRequest.new(
21 "https://myaccount.keepgo.com/api/v2/line/#{iccid}/get_details",
22 tls: { verify_peer: true }
23 ).aget(head: KEEPGO_HEADERS).then { |req|
24 SIM.extract(JSON.parse(req.response)&.dig("sim_card"))
25 }
26 end
27
28 def refill(sim, **kwargs)
29 iccid = sim.is_a?(String) ? sim : sim.iccid
30
31 EM::HttpRequest.new(
32 "https://myaccount.keepgo.com/api/v2/line/#{iccid}/refill",
33 tls: { verify_peer: true }
34 ).apost(
35 head: KEEPGO_HEADERS,
36 body: kwargs.to_json
37 ).then { |req| JSON.parse(req.response) }
38 end
39
40 def owned_by(customer)
41 customer = customer.customer_id if customer.respond_to?(:customer_id)
42 promise = db.query_defer(<<~SQL, [customer])
43 SELECT iccid, nickname FROM sims WHERE customer_id=$1
44 SQL
45 promise.then { |result|
46 EMPromise.all(result.map { |row|
47 find(row["iccid"]).then { |sim| sim.with(nickname: row["nickname"]) }
48 })
49 }
50 end
51
52 def put_owner(sim, customer, nickname=nil)
53 db.query_defer(<<~SQL, [customer.customer_id, sim.iccid, nickname])
54 UPDATE sims SET customer_id=$1, nickname=COALESCE($3, nickname) WHERE iccid=$2 AND customer_id IS NULL
55 SQL
56 end
57
58 def available
59 db.query_defer(<<~SQL).then { |r| find(r.first["iccid"]) }
60 SELECT iccid FROM sims WHERE customer_id IS NULL LIMIT 1
61 SQL
62 end
63end