<commit_before># frozen_string_literal: true
module ReviewBot
  GH = Github.new(oauth_token: ENV['GH_AUTH_TOKEN'])

  class Reminder
    attr_reader :owner, :repo, :app_config

    def initialize(owner, repo, app_config)
      @owner = owner
      @repo = repo
      @app_config = app_config
    end

    def message
      return if notifications.empty?

      # :smile_cat: https://github.com/danielma/reviewbot/pull/3 needs a first review from :dma: :dmas_evil_twin:
      message_header = ":smile_cat: :wave:\n"
      message_header + notifications.map(&:message).join("\n\n")
    end

    def app_reviewers
      @app_reviewers ||= app_config['reviewers'].map { |r| Reviewer.new(r) }
    end

    def out_reviewers
      return @out_reviewers if defined?(@out_reviewers)
      return @out_reviewers = [] unless bamboo_hr

      @out_reviewers ||=
        begin
          whos_out_ids = bamboo_hr
                         .whos_out(start_date: Date.today)
                         .map { |t| t['employeeId'] }
          app_reviewers.select { |r| whos_out_ids.include? r.bamboohr }
        end
    end

    def bamboo_hr
      return @bamboo_hr if defined?(@bamboo_hr)

      @bamboo_hr ||=
        if app_config['bamboohr_subdomain']
          BambooHR.new(
            api_key: ENV['BAMBOOHR_API_KEY'],
            subdomain: app_config['bamboohr_subdomain']
          )
        end
    end

    def notifications
      @notifications ||= potential_notifications.compact
    end

    def potential_notifications
      GH.pulls.list(owner, repo).body.map do |p|
        pull = PullRequest.new(p)

        print '.'

        next unless pull.needs_review?

        potential_reviewers = app_reviewers
                              .reject { |r| r.github == pull.user.login }
                              .reject { |r| out_reviewers.include? r }

        person_hours_since_last_touch = potential_reviewers.map do |reviewer|
          reviewer.work_hours_between(pull.last_touched_at, Time.now.utc)
        end.reduce(:+)

        next if person_hours_since_last_touch < app_config['hours_to_review']

        suggested_reviewers = potential_reviewers.reject do |reviewer|
          pull.reviewers.include?(reviewer['github'])
        end<commit_msg>fix(Reminder): work even if there are no reviewers<commit_after># frozen_string_literal: true
module ReviewBot
  GH = Github.new(oauth_token: ENV['GH_AUTH_TOKEN'])

  class Reminder
    attr_reader :owner, :repo, :app_config

    def initialize(owner, repo, app_config)
      @owner = owner
      @repo = repo
      @app_config = app_config
    end

    def message
      return if notifications.empty?

      # :smile_cat: https://github.com/danielma/reviewbot/pull/3 needs a first review from :dma: :dmas_evil_twin:
      message_header = ":smile_cat: :wave:\n"
      message_header + notifications.map(&:message).join("\n\n")
    end

    def app_reviewers
      @app_reviewers ||= app_config['reviewers'].map { |r| Reviewer.new(r) }
    end

    def out_reviewers
      return @out_reviewers if defined?(@out_reviewers)
      return @out_reviewers = [] unless bamboo_hr

      @out_reviewers ||=
        begin
          whos_out_ids = bamboo_hr
                         .whos_out(start_date: Date.today)
                         .map { |t| t['employeeId'] }
          app_reviewers.select { |r| whos_out_ids.include? r.bamboohr }
        end
    end

    def bamboo_hr
      return @bamboo_hr if defined?(@bamboo_hr)

      @bamboo_hr ||=
        if app_config['bamboohr_subdomain']
          BambooHR.new(
            api_key: ENV['BAMBOOHR_API_KEY'],
            subdomain: app_config['bamboohr_subdomain']
          )
        end
    end

    def notifications
      @notifications ||= potential_notifications.compact
    end

    def potential_notifications
      GH.pulls.list(owner, repo).body.map do |p|
        pull = PullRequest.new(p)

        print '.'

        next unless pull.needs_review?

        potential_reviewers = app_reviewers
                              .reject { |r| r.github == pull.user.login }
                              .reject { |r| out_reviewers.include? r }

        person_hours_since_last_touch = potential_reviewers.map do |reviewer|
          reviewer.work_hours_between(pull.last_touched_at, Time.now.utc)
        end.reduce(0, :+)

        next if person_hours_since_last_touch < app_config['hours_to_review']

        suggested_reviewers = potential_reviewers.reject do |reviewer|
          pull.reviewers.include?(reviewer['github'])
        end
{'fraction_non_alphanumeric': 0.09810822701275847, 'fraction_numerical': 0.0006599208095028596, 'mean_word_length': 2.32626188734455, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6058500', 'n_tokens_mistral': 1500, 'n_tokens_neox': 1412, 'n_words': 280}