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 support_call?(*)
 36			false
 37		end
 38
 39		def send_message?(*)
 40			false
 41		end
 42
 43		def credit_card_transaction?(*)
 44			false
 45		end
 46
 47		def create_subaccount?(*)
 48			false
 49		end
 50
 51		def to_s
 52			"Tomb"
 53		end
 54	end
 55
 56	class Basement
 57		TrustLevel.register do |manual:, settled_amount:, **|
 58			new if manual == "Basement" || (!manual && settled_amount < 10)
 59		end
 60
 61		def support_call?(rate, concurrency)
 62			rate <= 0.02 && concurrency < 1
 63		end
 64
 65		def send_message?(messages_today)
 66			messages_today < 50
 67		end
 68
 69		def credit_card_transaction?(amount, declines)
 70			amount <= 35 && declines <= 2
 71		end
 72
 73		def create_subaccount?(already_have)
 74			already_have < 2
 75		end
 76
 77		def to_s
 78			"Basement"
 79		end
 80	end
 81
 82	class Paragon
 83		TrustLevel.register do |manual:, settled_amount:, **|
 84			new if manual == "Paragon" || (!manual && settled_amount > 60)
 85		end
 86
 87		def support_call?(_, concurrency)
 88			concurrency < 10
 89		end
 90
 91		def send_message?(messages_today)
 92			messages_today < 700
 93		end
 94
 95		def credit_card_transaction?(amount, declines)
 96			amount <= 500 && declines <= 3
 97		end
 98
 99		def create_subaccount?(already_have)
100			already_have < 10
101		end
102
103		def to_s
104			"Paragon"
105		end
106	end
107
108	class Olympias
109		TrustLevel.register do |manual:, **|
110			new if manual == "Olympias"
111		end
112
113		def support_call?(*)
114			true
115		end
116
117		def send_message?(*)
118			true
119		end
120
121		def credit_card_transaction?(*)
122			true
123		end
124
125		def create_subaccount?(*)
126			true
127		end
128
129		def to_s
130			"Olympias"
131		end
132	end
133
134	class Customer
135		TrustLevel.register do |manual:, plan_name:, **|
136			if manual && manual != "Customer"
137				Sentry.capture_message("Unknown TrustLevel: #{manual}")
138			end
139
140			new(plan_name)
141		end
142
143		EXPENSIVE_ROUTE = {
144			"usd_beta_unlimited-v20210223" => 0.9,
145			"USD" => 0.9,
146			"cad_beta_unlimited-v20210223" => 1.1,
147			"CAD" => 1.1
148		}.freeze
149
150		def initialize(plan_name)
151			@max_rate = EXPENSIVE_ROUTE.fetch(plan_name, 0.1)
152		end
153
154		def support_call?(rate, concurrency)
155			rate <= @max_rate && concurrency < 4
156		end
157
158		def send_message?(messages_today)
159			messages_today < 500
160		end
161
162		def credit_card_transaction?(amount, declines)
163			amount <= 130 && declines <= 2
164		end
165
166		def create_subaccount?(already_have)
167			already_have < 2
168		end
169
170		def to_s
171			"Customer"
172		end
173	end
174end