<commit_before>class EffortSplitTimeCreator

  def initialize(args)
    ArgsValidator.validate(params: args,
                           required: [:row_time_data, :effort, :current_user_id],
                           exclusive: [:row_time_data, :effort, :current_user_id, :event, :military_times],
                           class: self.class)
    @row_time_data = args[:row_time_data]
    @effort = args[:effort]
    @current_user_id = args[:current_user_id]
    @event = args[:event] || effort.event
    @military_times = args[:military_times]
    set_start_offset
    validate_row_time_data
  end

  def split_times
    @split_times ||= populated_time_points.map { |time_point| split_time_build(time_point) }
  end

  def create_split_times
    SplitTime.bulk_insert do |worker|
      split_times.each do |split_time|
        worker.add(bulk_insert_attributes(split_time))
      end
    end
  end

  def bulk_insert_attributes(split_time)
    split_time.attributes.symbolize_keys.reject { |attr, _| [:id, :created_at, :updated_at].include?(attr) }
  end

  private

  EXCEL_BASE_DATETIME = '1899-12-30'.to_datetime
  CUTOVER_YEAR = 1910

  attr_reader :row_time_data, :effort, :current_user_id, :event

  def set_start_offset
    if military_times?
      effort.event_start_time = event.start_time # Avoids a database query to determine event_start_time
      effort.start_time = military_time_to_day_and_time(row_time_data.first, time_points.first)
    else
      effort.start_offset = time_to_seconds(row_time_data.first) || 0
      row_time_data[0] = 0 if row_time_data[0]
    end
    effort.save if effort.changed?
  end

  def split_time_build(time_point)
    SplitTime.new(effort_id: effort.id,
                  time_point: time_point,
                  time_from_start: convert_to_seconds(time_point),
                  created_by: current_user_id,
                  updated_by: current_user_id)
  end

  def convert_to_seconds(time_point)
    working_time = time_points_time_hash[time_point]
    military_times? ? military_time_to_seconds(working_time, time_point) : time_to_seconds(working_time)
  end

  def populated_time_points
    @populated_time_points ||= time_points.select { |time_point| time_points_time_hash[time_point].present? }
  end

  def time_points_time_hash
    @time_points_time_hash ||= time_points.zip(row_time_data).to_h
  end

  def time_points
    @time_points ||= event.laps_unlimited? ?
        event.cycled_time_points.first(row_time_data.size) :<commit_msg>Fix bug in EffortImporter that did not auto-fill zeros for start column in import spreadsheet.<commit_after>class EffortSplitTimeCreator

  def initialize(args)
    ArgsValidator.validate(params: args,
                           required: [:row_time_data, :effort, :current_user_id],
                           exclusive: [:row_time_data, :effort, :current_user_id, :event, :military_times],
                           class: self.class)
    @row_time_data = args[:row_time_data]
    @effort = args[:effort]
    @current_user_id = args[:current_user_id]
    @event = args[:event] || effort.event
    @military_times = args[:military_times]
    set_start_offset
    validate_row_time_data
  end

  def split_times
    @split_times ||= populated_time_points.map { |time_point| split_time_build(time_point) }
  end

  def create_split_times
    SplitTime.bulk_insert do |worker|
      split_times.each do |split_time|
        worker.add(bulk_insert_attributes(split_time))
      end
    end
  end

  def bulk_insert_attributes(split_time)
    split_time.attributes.symbolize_keys.reject { |attr, _| [:id, :created_at, :updated_at].include?(attr) }
  end

  private

  EXCEL_BASE_DATETIME = '1899-12-30'.to_datetime
  CUTOVER_YEAR = 1910

  attr_reader :row_time_data, :effort, :current_user_id, :event

  def set_start_offset
    if military_times?
      effort.event_start_time = event.start_time # Avoids a database query to determine event_start_time
      effort.start_time = military_time_to_day_and_time(row_time_data.first, time_points.first)
    else
      effort.start_offset = time_to_seconds(row_time_data.first) || 0
      row_time_data[0] = 0
    end
    effort.save if effort.changed?
  end

  def split_time_build(time_point)
    SplitTime.new(effort_id: effort.id,
                  time_point: time_point,
                  time_from_start: convert_to_seconds(time_point),
                  created_by: current_user_id,
                  updated_by: current_user_id)
  end

  def convert_to_seconds(time_point)
    working_time = time_points_time_hash[time_point]
    military_times? ? military_time_to_seconds(working_time, time_point) : time_to_seconds(working_time)
  end

  def populated_time_points
    @populated_time_points ||= time_points.select { |time_point| time_points_time_hash[time_point].present? }
  end

  def time_points_time_hash
    @time_points_time_hash ||= time_points.zip(row_time_data).to_h
  end

  def time_points
    @time_points ||= event.laps_unlimited? ?
        event.cycled_time_points.first(row_time_data.size) :
{'fraction_non_alphanumeric': 0.08302035975489228, 'fraction_numerical': 0.0061276932200039535, 'mean_word_length': 3.5299910474485228, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '1356043', 'n_tokens_mistral': 1745, 'n_tokens_neox': 1684, 'n_words': 286}