1# frozen_string_literal: true
2
3module MergeRequests
4  class OutdatedDiscussionDiffLinesService
5    include Gitlab::Utils::StrongMemoize
6
7    attr_reader :project, :note
8
9    OVERFLOW_LINES_COUNT = 2
10
11    def initialize(project:, note:)
12      @project = project
13      @note = note
14    end
15
16    def execute
17      line_position = position.line_range["end"] || position.line_range["start"]
18      found_line = false
19      diff_line_index = -1
20      diff_lines.each_with_index do |l, i|
21        if found_line
22          if !l.type
23            break
24          elsif l.type == 'new'
25            diff_line_index = i
26            break
27          end
28        else
29          # Find the old line
30          found_line = l.old_line == line_position["new_line"]
31        end
32
33        diff_line_index = i
34      end
35      initial_line_index = [diff_line_index - OVERFLOW_LINES_COUNT, 0].max
36      last_line_index = [diff_line_index + OVERFLOW_LINES_COUNT, diff_lines.length].min
37
38      prev_lines = []
39
40      diff_lines[initial_line_index..last_line_index].each do |line|
41        if line.meta?
42          prev_lines.clear
43        else
44          prev_lines << line
45        end
46      end
47
48      prev_lines
49    end
50
51    private
52
53    def position
54      note.change_position
55    end
56
57    def repository
58      project.repository
59    end
60
61    def diff_file
62      position.diff_file(repository)
63    end
64
65    def diff_lines
66      strong_memoize(:diff_lines) do
67        diff_file.highlighted_diff_lines
68      end
69    end
70  end
71end
72