# frozen_string_literal: true require "value_semantics/monkey_patched" require "uri" class CustomerFwd def self.for(uri:, timeout:) timeout = Timeout.new(timeout) return None.new(uri: uri, timeout: timeout) if !uri || timeout.zero? if uri =~ /\Asip:(.*)@sip.cheogram.com\Z/ uri = "xmpp:#{$1.gsub(/%([0-9A-F]{2})/i) { $1.to_i(16).chr }}" end URIS.fetch(uri.split(":", 2).first.to_sym) { raise "Unknown forward URI: #{uri}" }.new(uri: uri, timeout: timeout) end class Timeout def self.new(s) s.is_a?(self) ? s : super end def initialize(s) @timeout = s.nil? || s.to_i.negative? ? 300 : s.to_i end def zero? @timeout.zero? end def to_i @timeout end end value_semantics do uri Either(String, NilClass) def_attr :timeout, Timeout, coerce: Timeout.method(:new) end def with(new_attrs) CustomerFwd.for(to_h.merge(new_attrs)) end def create_call(account) request = Bandwidth::ApiCreateCallRequest.new.tap { |cc| cc.to = to cc.call_timeout = timeout.to_i yield cc if block_given? } BANDWIDTH_VOICE.create_call(account, body: request).data.call_id end def v2_sip? false end class Tel < CustomerFwd def to uri.sub(/^tel:/, "") end end class SIP < CustomerFwd def v2_sip? uri.end_with?(CONFIG[:sip][:realm]) end def to uri end end class XMPP < CustomerFwd def to jid = uri.sub(/^xmpp:/, "") "sip:#{ERB::Util.url_encode(jid)}@sip.cheogram.com" end end class None < CustomerFwd def create_call; end def to; end end URIS = { tel: Tel, sip: SIP, xmpp: XMPP }.freeze end