1# frozen_string_literal: true
  2
  3require "delegate"
  4
  5module TrustLevel
  6	def self.for(plan_name:, settled_amount: 0, manual: nil)
  7		@levels.each do |level|
  8			tl = level.call(
  9				plan_name: plan_name,
 10				settled_amount: settled_amount,
 11				manual: manual
 12			)
 13			return manual ? Manual.new(tl) : tl if tl
 14		end
 15
 16		raise "No TrustLevel matched"
 17	end
 18
 19	def self.register(&maybe_mk)
 20		@levels ||= []
 21		@levels << maybe_mk
 22	end
 23
 24	class Manual < SimpleDelegator
 25		def to_s
 26			"Manual(#{super})"
 27		end
 28	end
 29
 30	class Tomb
 31		TrustLevel.register do |manual:, **|
 32			new if manual == "Tomb"
 33		end
 34
 35		def write_cdr?
 36			false
 37		end
 38
 39		def support_call?(*)
 40			false
 41		end
 42
 43		def send_message?(*)
 44			false
 45		end
 46
 47		def credit_card_transaction?(*)
 48			false
 49		end
 50
 51		def create_subaccount?(*)
 52			false
 53		end
 54
 55		def to_s
 56			"Tomb"
 57		end
 58	end
 59
 60	class Basement
 61		TrustLevel.register do |manual:, settled_amount:, **|
 62			new if manual == "Basement" || (!manual && settled_amount < 10)
 63		end
 64
 65		def write_cdr?
 66			true
 67		end
 68
 69		def support_call?(rate, concurrency)
 70			rate <= 0.02 && concurrency < 1
 71		end
 72
 73		def send_message?(messages_today)
 74			messages_today < 40
 75		end
 76
 77		def credit_card_transaction?(amount, declines)
 78			amount <= 35 && declines <= 2
 79		end
 80
 81		def create_subaccount?(already_have)
 82			already_have < 2
 83		end
 84
 85		def to_s
 86			"Basement"
 87		end
 88	end
 89
 90	class Paragon
 91		TrustLevel.register do |manual:, settled_amount:, **|
 92			new if manual == "Paragon" || (!manual && settled_amount > 60)
 93		end
 94
 95		def write_cdr?
 96			true
 97		end
 98
 99		def support_call?(_, concurrency)
100			concurrency < 10
101		end
102
103		def send_message?(messages_today)
104			messages_today < 700
105		end
106
107		def credit_card_transaction?(amount, declines)
108			amount <= 500 && declines <= 3
109		end
110
111		def create_subaccount?(already_have)
112			already_have < 10
113		end
114
115		def to_s
116			"Paragon"
117		end
118	end
119
120	class Olympias
121		TrustLevel.register do |manual:, **|
122			new if manual == "Olympias"
123		end
124
125		def write_cdr?
126			true
127		end
128
129		def support_call?(*)
130			true
131		end
132
133		def send_message?(*)
134			true
135		end
136
137		def credit_card_transaction?(*)
138			true
139		end
140
141		def create_subaccount?(*)
142			true
143		end
144
145		def to_s
146			"Olympias"
147		end
148	end
149
150	class Customer
151		TrustLevel.register do |manual:, plan_name:, **|
152			if manual && manual != "Customer"
153				Sentry.capture_message("Unknown TrustLevel: #{manual}")
154			end
155
156			new(plan_name)
157		end
158
159		EXPENSIVE_ROUTE = {
160			"usd_beta_unlimited-v20210223" => 0.9,
161			"USD" => 0.9,
162			"cad_beta_unlimited-v20210223" => 1.1,
163			"CAD" => 1.1
164		}.freeze
165
166		def initialize(plan_name)
167			@max_rate = EXPENSIVE_ROUTE.fetch(plan_name, 0.1)
168		end
169
170		def write_cdr?
171			true
172		end
173
174		def support_call?(rate, concurrency)
175			rate <= @max_rate && concurrency < 4
176		end
177
178		def send_message?(messages_today)
179			messages_today < 500
180		end
181
182		def credit_card_transaction?(amount, declines)
183			amount <= 130 && declines <= 2
184		end
185
186		def create_subaccount?(already_have)
187			already_have < 2
188		end
189
190		def to_s
191			"Customer"
192		end
193	end
194end