1# frozen_string_literal: true
2
3require "em_promise"
4require "delegate"
5require "ruby-bandwidth-iris"
6require "lazy_object"
7
8require_relative "db_port"
9
10class PortRepo
11 def initialize(output, dry_run: false)
12 @output = output
13 @dry_run = dry_run
14 @step_repo = PortingStepRepo.new(output: output)
15 end
16
17 def list
18 raise NotImplementedError, "subclass must implement"
19 end
20
21 def process
22 list.then { |ports|
23 EMPromise.all(ports.map(&method(:tick)))
24 }
25 end
26
27 class Bandwidth < self
28 class PortWithBackend < SimpleDelegator
29 def backend_sgx
30 CONFIG[:sgx]
31 end
32
33 def id
34 self[:order_id]
35 end
36
37 def customer_id
38 self[:customer_order_id]
39 end
40
41 def tel
42 self[:billing_telephone_number]
43 end
44
45 def updated_at
46 self[:last_modified_date]
47 end
48 end
49
50 def list
51 (BandwidthIris::PortIn.list(
52 page: 1,
53 size: 50,
54 start_date: Date.today - 1,
55 end_date: Date.today
56 ) || []).map(&PortWithBackend.method(:new))
57 end
58 end
59
60 class Db < self
61 def initialize(
62 output,
63 dry_run: false,
64 db: LazyObject.new { DB },
65 filters: {}
66 )
67 super(output, dry_run: dry_run)
68 @db = db
69 @filters = filters
70 end
71
72 def list(**kwargs)
73 rows(**@filters.merge(kwargs)).then { |r|
74 r.map { |row|
75 DbPort.from(**row.transform_keys(&:to_sym))
76 }
77 }
78 end
79
80 protected
81
82 def rows(
83 max_results: 50,
84 offset: 0,
85 start_date: Date.today - 1,
86 end_date: Date.today + 1,
87 customer_id: nil
88 )
89 conditions = ["actual_foc_date >= $1", "actual_foc_date <= $2"]
90 params = [start_date, end_date]
91
92 if customer_id
93 conditions << "customer_id = $#{params.length + 1}"
94 params << customer_id
95 end
96
97 @db.exec_defer(<<~SQL, params + [max_results, offset])
98 SELECT * FROM ports
99 WHERE #{conditions.join(' AND ')}
100 LIMIT $#{params.length + 1}
101 OFFSET $#{params.length + 2}
102 SQL
103 end
104 end
105
106 class Fake < Bandwidth
107 FakePort = Struct.new(
108 :id,
109 :processing_status,
110 :actual_foc_date,
111 :updated_at,
112 :customer_id,
113 :tel,
114 :backend_sgx
115 )
116
117 def list
118 minutes = 1.0 / (24 * 60)
119
120 [
121 # This should be ignored
122 FakePort.new(
123 "T01", "SUBMITTED", nil, DateTime.now - 1,
124 "ignored", "9998887777", "testroute"
125 ),
126 FakePort.new(
127 "T02", "COMPLETE", DateTime.now - (60 * minutes),
128 DateTime.now - (55 * minutes), "0001", "2223334444", "testroute"
129 )
130 ]
131 end
132 end
133
134protected
135
136 def tick(port)
137 @step_repo.find(port).then { |step|
138 @output.info(port.id, :class, step.class)
139 if @dry_run
140 @output.info("DRY", :dry, "Not taking action")
141 else
142 step.perform_next_step
143 end
144 }
145 end
146end