# frozen_string_literal: true

#
# Copyright (C) 2020 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module Auditors::ActiveRecord
  class GradeChangeRecord < ActiveRecord::Base
    include Auditors::ActiveRecord::Attributes
    include CanvasPartman::Concerns::Partitioned
    self.partitioning_strategy = :by_date
    self.partitioning_interval = :months
    self.partitioning_field = 'created_at'
    self.table_name = 'auditor_grade_change_records'

    belongs_to :account, inverse_of: :auditor_grade_change_records
    belongs_to :root_account, class_name: 'Account', inverse_of: :auditor_root_grade_change_records, foreign_key: 'root_account_id'
    belongs_to :student, class_name: 'User', inverse_of: :auditor_student_grade_change_records, foreign_key: 'student_id'
    belongs_to :grader, class_name: 'User', inverse_of: :auditor_grader_grade_change_records, foreign_key: 'grader_id'
    belongs_to :submission, inverse_of: :auditor_grade_change_records
    belongs_to :course, -> { where(context_type: 'Course') }, class_name: "::Course", foreign_key: 'context_id', inverse_of: :auditor_grade_change_records
    belongs_to :assignment, inverse_of: :auditor_grade_change_records
    belongs_to :grading_period, inverse_of: :auditor_grade_change_records

    attr_accessor :grade_current

    class << self
      include Auditors::ActiveRecord::Model

      def ar_attributes_from_event_stream(record)
        attrs_hash = record.attributes.except('id', 'version_number')
        root_account_id = Account.where(id: record.account_id).pluck(:root_account_id).first
        attrs_hash['request_id'] ||= "MISSING"
        attrs_hash['uuid'] = record.id
        attrs_hash['account_id'] = Shard.relative_id_for(record.account_id, Shard.current, Shard.current)
        attrs_hash['root_account_id'] = (root_account_id || attrs_hash['account_id'])
        attrs_hash['assignment_id'] = resolve_id_or_placeholder(record.assignment_id)
        attrs_hash['context_id'] = Shard.relative_id_for(record.context_id, Shard.current, Shard.current)
        attrs_hash['grader_id'] = Shard.relative_id_for(record.grader_id, Shard.current, Shard.current)
        attrs_hash['graded_anonymously'] ||= false
        attrs_hash['student_id'] = Shard.relative_id_for(record.student_id, Shard.current, Shard.current)
        attrs_hash['submission_id'] = resolve_id_or_placeholder(record.submission_id)
        attrs_hash['submission_version_number'] = record.version_number
        attrs_hash['grading_period_id'] = resolve_id_or_placeholder(record.grading_period_id)
        attrs_hash
      end
    end

    def course_id
      return nil unless context_type == 'Course'
      context_id
    end

    def version_number
      submission_version_number
    end

    def override_grade?
      submission_id.blank?
    end

    def in_grading_period?
      grading_period_id.present?
    end

    def self.resolve_id_or_placeholder(id)
      return nil if id == Auditors::GradeChange::NULL_PLACEHOLDER
      Shard.relative_id_for(id, Shard.current, Shard.current)
    end
    private_class_method :resolve_id_or_placeholder
  end
end
