1# frozen_string_literal: true
 2
 3require "multibases"
 4require "securerandom"
 5
 6require_relative "customer"
 7require_relative "trust_level_repo"
 8
 9class ParentCodeRepo
10	def initialize(
11		redis: REDIS,
12		db: DB,
13		trust_level_repo: TrustLevelRepo.new(redis: redis, db: db)
14	)
15		@redis = redis
16		@db = db
17		@trust_level_repo = trust_level_repo
18	end
19
20	def find(code)
21		@redis.hget("jmp_parent_codes", code).then do |parent_id|
22			trust_level_guard(parent_id).then { parent_id }
23		end
24	end
25
26	def find_or_create(customer_id)
27		trust_level_guard(customer_id).then {
28			@redis.get("jmp_customer_parent_code-#{customer_id}")
29		}.then do |code|
30			next code if code
31
32			code = "p#{Multibases.pack('base32upper', SecureRandom.bytes(4))}"
33			EMPromise.all([
34				@redis.set("jmp_customer_parent_code-#{customer_id}", code),
35				@redis.hset("jmp_parent_codes", code, customer_id)
36			]).then { code }
37		end
38	end
39
40	def existing_subaccounts(parent_id)
41		@db.query_one(<<~SQL, parent_id, default: { c: 0 }).then { |r| r[:c] }
42			SELECT COUNT(*) AS c FROM customer_plans WHERE parent_customer_id=$1
43		SQL
44	end
45
46	def trust_level_guard(parent_id)
47		return unless parent_id
48
49		@trust_level_repo.find(Customer.new(parent_id, "", sgx: nil)).then { |tl|
50			existing_subaccounts(parent_id).then { |c| [tl, c] }
51		}.then do |(tl, number_of_subaccounts)|
52			unless tl.create_subaccount?(number_of_subaccounts)
53				raise "Please contact support to create a subaccount"
54			end
55		end
56	end
57end