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