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