1# frozen_string_literal: true
2
3require "forwardable"
4require "ruby-bandwidth-iris"
5require "faraday/em_synchrony"
6Faraday.default_adapter = :em_synchrony
7
8class BandwidthTNOrder
9 ORDER_DEFAULTS = {
10 site_id: CONFIG[:bandwidth_site],
11 peer_id: CONFIG[:bandwidth_peer]
12 }.freeze
13
14 def self.get(id)
15 EMPromise.resolve(nil).then do
16 self.for(BandwidthIris::Order.get_order_response(
17 # https://github.com/Bandwidth/ruby-bandwidth-iris/issues/44
18 BandwidthIris::Client.new,
19 id
20 ))
21 end
22 end
23
24 def self.create(
25 tel,
26 name: "sgx-jmp order #{tel}",
27 reservation_id: nil,
28 **kwargs
29 )
30 create_custom(
31 name: name, **kwargs,
32 existing_telephone_number_order_type: {
33 telephone_number_list: { telephone_number: [tel.sub(/^\+?1?/, "")] }
34 }.merge(ReservationIdList.new(reservation_id).to_h)
35 )
36 end
37
38 def self.create_custom(name:, **kwargs)
39 EMPromise.resolve(nil).then do
40 Received.new(BandwidthIris::Order.create(
41 name: name, **ORDER_DEFAULTS, **kwargs
42 ))
43 end
44 end
45
46 def self.for(bandwidth_order)
47 const_get(bandwidth_order.order_status.capitalize).new(bandwidth_order)
48 rescue NameError
49 new(bandwidth_order)
50 end
51
52 extend Forwardable
53 def_delegators :@order, :id
54
55 def initialize(bandwidth_order)
56 @order = bandwidth_order
57 end
58
59 def status
60 @order[:order_status]&.downcase&.to_sym
61 end
62
63 def error_description
64 [@order[:error_list]].flatten.first&.dig(:error, :description)
65 end
66
67 def poll
68 raise "Unknown order status: #{status}"
69 end
70
71 class Received < BandwidthTNOrder
72 def status
73 :received
74 end
75
76 def poll
77 EM.promise_timer(1).then do
78 BandwidthTNOrder.get(id).then(&:poll)
79 end
80 end
81 end
82
83 class Complete < BandwidthTNOrder
84 def status
85 :complete
86 end
87
88 def tel
89 tels[0]
90 end
91
92 def tels
93 tns = @order.completed_numbers[:telephone_number]
94 (tns.is_a?(Array) ? tns : [tns]).map do |item|
95 "+1#{item[:full_number]}"
96 end
97 end
98
99 def poll
100 EMPromise.resolve(self)
101 end
102 end
103
104 class Failed < BandwidthTNOrder
105 def status
106 :failed
107 end
108
109 def poll
110 raise "Order failed: #{id} #{error_description}"
111 end
112 end
113
114 class ReservationIdList
115 def initialize(reservation_id)
116 @reservation_id = reservation_id
117 end
118
119 def to_h
120 return {} unless @reservation_id
121
122 { reservation_id_list: { reservation_id: @reservation_id } }
123 end
124 end
125end