1# frozen_string_literal: true
 2
 3require "value_semantics/monkey_patched"
 4
 5require_relative "customer"
 6require_relative "form_template"
 7require_relative "form_to_h"
 8require_relative "reachability_repo"
 9
10class ReachabilityForm
11	using FormToH
12
13	REPOS = {
14		"sms" => ReachabilityRepo::SMS,
15		"voice" => ReachabilityRepo::Voice
16	}.freeze
17
18	class Result
19		value_semantics do
20			repo ReachabilityRepo
21			target Customer
22			sender Either(String, nil)
23		end
24
25		def prompt
26			return unless sender
27
28			Blather::Stanza::Message.new.tap do |m|
29				m.body = "/#{repo.type}"
30				# stanza_from will fix domain
31				m.to = Blather::JID.new("#{sender}@sgx-jmp")
32			end
33		end
34	end
35
36	def initialize(customer_repo)
37		@customer_repo = customer_repo
38	end
39
40	def render
41		FormTemplate.render("reachability")
42	end
43
44	def render_result(count)
45		FormTemplate.render("reachability_result", count: count)
46	end
47
48	def parse(form)
49		params = form.to_h
50		tel = cleanup_tel(params["tel"])
51
52		sender = cleanup_sender(params["reachability_tel"])
53
54		repo = REPOS[params["type"]]
55		raise "Type is invalid" unless repo
56
57		find_target(tel).then { |target|
58			Result.new(target: target, repo: repo.new, sender: sender)
59		}
60	end
61
62protected
63
64	def find_target(tel)
65		@customer_repo.find_by_tel(tel)
66	end
67
68	def cleanup_sender(str)
69		return nil unless str
70
71		str = str.strip
72		return nil if str.empty?
73
74		unless CONFIG[:reachability_senders].include?(str)
75			raise "Sender not in whitelist"
76		end
77
78		str
79	end
80
81	def cleanup_tel(str)
82		"+1#{str.gsub(/\A\+?1?/, '')}"
83	end
84end