# frozen_string_literal: true

class PentestChallenge < Challenge
  include ShareCalculationModule

  # The default scope on Challenge is order(:point_value, :created_at).
  # Point value operates a bit differently for PentestChallenges, instead we just order their display by created_at time
  default_scope -> { reorder(:created_at) }

  has_many :defense_flags, inverse_of: :challenge, foreign_key: 'challenge_id', dependent: :destroy,
                           class_name: 'DefenseFlag'

  has_many :solved_challenges, foreign_key: 'challenge_id', inverse_of: :challenge, dependent: :destroy,
                               class_name: 'PentestSolvedChallenge'

  accepts_nested_attributes_for :defense_flags, allow_destroy: true

  validates :defense_period, :unsolved_increment_period, numericality: { greater_than: 0 }

  def get_solved_challenge_for(team, flag)
    # Persisted ones are saved in the database, this ensures that when we are getting
    # solved challenges we only show ones that are successfully validated and saved
    solved_challenges.filter(&:persisted?).find { |sc| sc.team_id.eql?(team&.id) && sc.flag_id.eql?(flag&.id) }
  end

  # Teams cannot solve a challenge if they are the owner of the flag or if they have already solved it
  def can_be_solved_by(team, flag)
    get_solved_challenge_for(team, flag).nil? && !team.eql?(flag&.team)
  end

  def calc_defensive_points_helper(start_time, end_time)
    ((end_time - start_time) / defense_period.hours) * defense_points
  end

  def next_challenge
    pentest_challenges = game.pentest_challenges
    index = pentest_challenges.find_index(self)
    pentest_challenges[index + 1] unless index.nil?
  end
end
