<commit_before>require 'thread'

module Discuss
  class Message < ActiveRecord::Base
    has_ancestry

    attr_accessor :draft, :draft_recipients
    serialize :draft_recipient_ids, Array

    belongs_to :user, polymorphic: true

    validates :body, :user, presence: true
    validate :lock_down_attributes, on: :update

    scope :ordered,      -> { order('created_at asc') }
    scope :active,       -> { not_trashed.not_deleted }

    scope :draft,        -> { where('sent_at is NULL') }
    scope :not_draft,    -> { where('sent_at is not NULL')  }

    scope :sent,         -> { where('sent_at is not NULL') }
    scope :unsent,       -> { where('sent_at is NULL')  }

    scope :received,     -> { where('received_at is not NULL') }
    scope :not_received, -> { where('received_at is NULL') }

    scope :trashed,      -> { where('trashed_at is not NULL') }
    scope :not_trashed,  -> { where('trashed_at is NULL') }

    scope :deleted,      -> { where('deleted_at is not NULL') }
    scope :not_deleted,  -> { where('deleted_at is NULL') }

    scope :by_user, lambda { |user| where(user: user) }
    scope :inbox,   lambda { |user| by_user(user).active.received }
    scope :outbox,  lambda { |user| by_user(user).active.sent }
    scope :drafts,  lambda { |user| by_user(user).active.draft.not_received }
    scope :trash,   lambda { |user| by_user(user).trashed.not_deleted }

    scope :read,    lambda { |user| by_user(user).where('read_at is not NULL').received }
    scope :unread,  lambda { |user| by_user(user).where('read_at is NULL').received }

    def active?
      !trashed? && !deleted?
    end

    def sender
      if sent?
        user
      else
        parent ? parent.user : user
      end
    end

    def recipients
      sent? ? children.collect(&:user) : parent.recipients
    end

    def draft_recipients
      self.draft_recipient_ids.map { |id| Discuss::RecipientSerializer.from_hash(id).recipient }
    end

    def draft_recipients= recipients
      self.draft_recipient_ids = recipients.map { |r| Discuss::RecipientSerializer.new(r).to_hash }
    end

    def mailbox
      case
      when sent? then :outbox
      when received? then :inbox
      when !new_record? && unsent? then :drafts
      when trashed? then :trash
      else
        :compose
      end
    end

    def send!
      lock.synchronize do
        Discuss::MessageSender.new(self).run unless draft?<commit_msg>Add fallback recipients if message doesn't have a parent and is unsent<commit_after>require 'thread'

module Discuss
  class Message < ActiveRecord::Base
    has_ancestry

    attr_accessor :draft
    serialize :draft_recipient_ids, Array

    belongs_to :user, polymorphic: true

    validates :body, :user, presence: true
    validate :lock_down_attributes, on: :update

    scope :ordered,      -> { order('created_at asc') }
    scope :active,       -> { not_trashed.not_deleted }

    scope :draft,        -> { where('sent_at is NULL') }
    scope :not_draft,    -> { where('sent_at is not NULL')  }

    scope :sent,         -> { where('sent_at is not NULL') }
    scope :unsent,       -> { where('sent_at is NULL')  }

    scope :received,     -> { where('received_at is not NULL') }
    scope :not_received, -> { where('received_at is NULL') }

    scope :trashed,      -> { where('trashed_at is not NULL') }
    scope :not_trashed,  -> { where('trashed_at is NULL') }

    scope :deleted,      -> { where('deleted_at is not NULL') }
    scope :not_deleted,  -> { where('deleted_at is NULL') }

    scope :by_user, lambda { |user| where(user: user) }
    scope :inbox,   lambda { |user| by_user(user).active.received }
    scope :outbox,  lambda { |user| by_user(user).active.sent }
    scope :drafts,  lambda { |user| by_user(user).active.draft.not_received }
    scope :trash,   lambda { |user| by_user(user).trashed.not_deleted }

    scope :read,    lambda { |user| by_user(user).where('read_at is not NULL').received }
    scope :unread,  lambda { |user| by_user(user).where('read_at is NULL').received }

    def active?
      !trashed? && !deleted?
    end

    def sender
      if sent?
        user
      else
        parent ? parent.user : user
      end
    end

    def recipients
      if sent?
        children.collect(&:user)
      elsif parent.present?
        parent.recipients
      else
        draft_recipients
      end
    end

    def draft_recipients
      self.draft_recipient_ids.map { |id| Discuss::RecipientSerializer.from_hash(id).recipient }
    end

    def draft_recipients= recipients
      self.draft_recipient_ids = recipients.map { |r| Discuss::RecipientSerializer.new(r).to_hash }
    end

    def mailbox
      case
      when sent? then :outbox
      when received? then :inbox
      when !new_record? && unsent? then :drafts
      when trashed? then :trash
      else
        :compose
      end
    end

    def send!
      lock.synchronize do
        Discuss::MessageSender.new(self).run unless draft?
{'fraction_non_alphanumeric': 0.11562437160667605, 'fraction_numerical': 0.0, 'mean_word_length': 2.6306569343065695, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 27, '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': '4912100', 'n_tokens_mistral': 1644, 'n_tokens_neox': 1569, 'n_words': 409}