class Kuroko2::JobDefinition

def confirm_active_instances

def confirm_active_instances
  if Kuroko2::Token.joins(:job_instance).merge(job_instances).exists?
    errors.add(:base, I18n.t('model.job_definition.confirm_active_instances'))
    throw :abort
  end
end

def create_default_memory_expectancy

def create_default_memory_expectancy
  create_memory_expectancy! unless memory_expectancy
end

def create_instance(script: nil, launched_by:, token: nil )

def create_instance(script: nil, launched_by:, token: nil )
  message = "Launched by #{launched_by}"
  if token.present?
    message = "(token #{token.uuid}) #{message}"
  end
  job_instances.create!(script: script, log_message: message)
end

def proceed_multi_instance?

def proceed_multi_instance?
  tokens = Kuroko2::Token.where(job_definition_id: self.id)
  (tokens.map(&:status) & PREVENT_TOKEN_STATUSES[self.prevent_multi]).empty?
end

def record_revision(edited_user: nil)

def record_revision(edited_user: nil)
  unless revisions.first.try(:script) == script
    revisions.create!(script: script, user: edited_user, changed_at: Time.current)
  end
  nil
end

def save_and_record_revision(edited_user: nil)

def save_and_record_revision(edited_user: nil)
  transaction do
    if save
      record_revision(edited_user: edited_user)
      true
    else
      false
    end
  end
end

def script_syntax

def script_syntax
  Kuroko2::Workflow::ScriptParser.new(script).parse
  true
rescue Kuroko2::Workflow::SyntaxError => e
  errors.add(:base, I18n.t('model.job_definition.script_syntax', reason: e.message))
  false
rescue Kuroko2::Workflow::AssertionError => e
  errors.add(:base, I18n.t('model.job_definition.validation_error', reason: e.message))
  false
end

def set_default_values

def set_default_values
  self.description ||= <<-EOF.strip_heredoc
    An description of the job definition.
    ## Failure Affects
    Affected users, services and/ or business areas.
    ## Workaround
    Choose one of the following:
    - __Retry__ as soon as possible.
    - Make an urgent call to administrator (Job stays in _Error_ state)
    - Do nothing, and let administrator recover later (Job stays in _Error_ state)
    - Ignore error and _Cancel_ the job (No recovery required)
    ## Recovery Procedures
    Describe how to recover from the failure.
  EOF
end

def text_tags

def text_tags
  tags.map(&:name).join(',')
end

def text_tags=(text_tags)

def text_tags=(text_tags)
  self.tags = text_tags.gsub(/[[:blank:]]+/, '').split(/[,、]/).uniq.map do |name|
    Kuroko2::Tag.find_or_create_by(name: name)
  end
end

def update_and_record_revision(attributes, edited_user: nil)

def update_and_record_revision(attributes, edited_user: nil)
  assign_attributes(attributes)
  transaction do
    if save
      record_revision(edited_user: edited_user)
      true
    else
      false
    end
  end
end

def validate_number_of_admins

def validate_number_of_admins
  if self.admins.empty?
    errors.add(:admins, I18n.t('model.job_definition.validate_number_of_admins'))
  end
end