# frozen_string_literal: true

#
# Copyright (C) 2013 - 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/>.
#

require_relative "report_spec_helper"

describe "Course Account Reports" do
  include ReportSpecHelper

  before(:once) do
    Notification.where(name: "Report Generated").first_or_create
    Notification.where(name: "Report Generation Failed").first_or_create
    @account = Account.create(name: "New Account", default_time_zone: "UTC")
    @admin = account_admin_user(account: @account)
    @default_term = @account.default_enrollment_term

    @sub_account = Account.create(parent_account: @account, name: "Math")
    @sub_account.sis_source_id = "sub1"
    @sub_account.save!

    @term1 = EnrollmentTerm.create(name: "Fall",
                                   start_at: 6.months.ago,
                                   end_at: 1.year.from_now)
    @term1.root_account = @account
    @term1.sis_source_id = "fall12"
    @term1.save!

    start_at = 1.day.ago
    end_at = 3.months.from_now
    @course1 = Course.create(name: "English 101",
                             course_code: "ENG101",
                             start_at:,
                             conclude_at: end_at,
                             account: @sub_account,
                             enrollment_term: @term1)
    @course1.sis_source_id = "SIS_COURSE_ID_1"
    @course1.restrict_enrollments_to_course_dates = true
    @course1.save!

    @course2 = Course.create(name: "Math 101",
                             course_code: "MAT101",
                             conclude_at: end_at,
                             account: @account)
    @course2.sis_source_id = "SIS_COURSE_ID_2"
    @course2.save!
    @course2.destroy

    @course3 = Course.create(name: "Science 101",
                             course_code: "SCI101",
                             account: @account)
    @course3.workflow_state = "claimed"
    @course3.sis_source_id = "SIS_COURSE_ID_3"
    @course3.save!

    @course4 = Course.create(name: "self help",
                             course_code: "self",
                             account: @account)
    @course4.offer

    @course5 = Course.create(name: "talking 101",
                             course_code: "Tal101",
                             account: @account)
    @course5.workflow_state = "completed"
    @course5.save!
  end

  describe "unpublished courses" do
    before do
      @report = "unpublished_courses_csv"
    end

    it "runs unpublished courses report on a term" do
      parameters = {}
      parameters["enrollment_term_id"] = @default_term.id
      parsed = read_report(@report, { params: parameters })

      expect(parsed).to eq [[@course3.id.to_s,
                             "SIS_COURSE_ID_3",
                             "SCI101",
                             "Science 101",
                             nil,
                             nil]]
      expect(parsed.length).to eq 1
    end

    it "runs unpublished courses report on sub account" do
      parsed = read_report(@report, { account: @sub_account })

      expect(parsed).to eq [[@course1.id.to_s,
                             "SIS_COURSE_ID_1",
                             "ENG101",
                             "English 101",
                             @course1.start_at.iso8601,
                             @course1.conclude_at.iso8601]]
      expect(parsed.length).to eq 1
    end

    it "runs unpublished courses report" do
      parsed = read_report(@report, { order: 1 })
      expect(parsed).to eq [[@course1.id.to_s,
                             "SIS_COURSE_ID_1",
                             "ENG101",
                             "English 101",
                             @course1.start_at.iso8601,
                             @course1.conclude_at.iso8601],
                            [@course3.id.to_s,
                             "SIS_COURSE_ID_3",
                             "SCI101",
                             "Science 101",
                             nil,
                             nil]]
      expect(parsed.length).to eq 2
    end
  end

  describe "deleted courses" do
    before do
      @report = "recently_deleted_courses_csv"
    end

    it "runs recently deleted courses report on a term" do
      @course1.destroy
      parameters = {}
      parameters["enrollment_term_id"] = @default_term.id
      parsed = read_report(@report, { params: parameters })

      expect(parsed[0]).to eq [@course2.id.to_s,
                               "SIS_COURSE_ID_2",
                               "MAT101",
                               "Math 101",
                               nil,
                               nil]
      expect(parsed.length).to eq 1
    end

    it "runs recently deleted courses report on sub account" do
      @course1.destroy
      parsed = read_report(@report, { account: @sub_account })

      expect(parsed[0]).to eq [@course1.id.to_s,
                               "SIS_COURSE_ID_1",
                               "ENG101",
                               "English 101",
                               @course1.start_at.iso8601,
                               @course1.conclude_at.iso8601]
      expect(parsed.length).to eq 1
    end

    it "runs recently deleted courses report" do
      @course1.destroy
      parsed = read_report(@report, { order: 1 })
      expect(parsed.length).to eq 2

      expect(parsed[0]).to eq [@course1.id.to_s,
                               "SIS_COURSE_ID_1",
                               "ENG101",
                               "English 101",
                               @course1.start_at.iso8601,
                               @course1.conclude_at.iso8601]
      expect(parsed[1]).to eq [@course2.id.to_s,
                               "SIS_COURSE_ID_2",
                               "MAT101",
                               "Math 101",
                               nil,
                               nil]
    end
  end

  describe "Unused Course report" do
    before(:once) do
      @type = "unused_courses_csv"

      @course6 = Course.create(name: "Theology 101",
                               course_code: "THE01",
                               account: @account)

      @assignment = @course1.assignments.create(title: "some assignment",
                                                points_possible: "5")

      @assignment.sub_assignments.create!(title: "sub assignment", context: @assignment.context, sub_assignment_tag: CheckpointLabels::REPLY_TO_TOPIC)
      @discussion = @course2.discussion_topics.create!(message: "hi")
      @attachment = attachment_model(context: @course3)
      @module = @course4.context_modules.create!(name: "some module")
      @quiz = @course5.quizzes.create!(title: "new quiz")
    end

    it "finds courses with no active objects" do
      @assignment.destroy
      @attachment.destroy

      parsed = read_report(@type, { order: 3 })
      expect(parsed.length).to eq 3

      expect(parsed[0]).to eq [@course1.id.to_s,
                               "SIS_COURSE_ID_1",
                               "ENG101",
                               "English 101",
                               "unpublished",
                               @course1.created_at.iso8601]
      expect(parsed[1]).to eq [@course3.id.to_s,
                               "SIS_COURSE_ID_3",
                               "SCI101",
                               "Science 101",
                               "unpublished",
                               @course3.created_at.iso8601]
      expect(parsed[2]).to eq [@course6.id.to_s,
                               nil,
                               "THE01",
                               "Theology 101",
                               "unpublished",
                               @course6.created_at.iso8601]
    end

    it "does not find courses with objects" do
      @wiki_page = @course6.wiki_pages.create(
        title: "Some random wiki page",
        body: "wiki page content"
      )
      report = run_report(@type)
      expect(report.parameters["extra_text"]).to eq "Term: All Terms;"
      parsed = parse_report(report)
      expect(parsed.length).to eq 0
    end

    it "sets run_at" do
      report = run_report(@type)
      expect(report.start_at).not_to be_nil
    end

    it "runs unused courses report with a term" do
      @term1 = @account.enrollment_terms.create(name: "Fall")
      @assignment.destroy
      @course5.enrollment_term = @term1
      @course5.save
      @course6.enrollment_term = @term1
      @course6.save
      parameters = {}
      parameters["enrollment_term_id"] = @term1.id
      parsed = read_report(@type, { params: parameters })
      expect(parsed.length).to eq 1

      expect(parsed[0]).to eq [@course6.id.to_s,
                               nil,
                               "THE01",
                               "Theology 101",
                               "unpublished",
                               @course6.created_at.iso8601]
    end

    it "runs unused courses report on a sub account" do
      sub_account = Account.create(parent_account: @account,
                                   name: "English")
      @course3.account = sub_account
      @course3.save
      @course4.account = sub_account
      @course4.save
      @module.destroy
      parsed = read_report(@type, { account: sub_account })
      expect(parsed.length).to eq 1

      expect(parsed[0]).to eq [@course4.id.to_s,
                               nil,
                               "self",
                               "self help",
                               "active",
                               @course4.created_at.iso8601]
    end
  end

  describe "course storage report" do
    before(:once) do
      @report = "course_storage_csv"
      a = attachment_obj_with_context(@course1)
      a.update_attribute(:size, 1.226.decimal_megabytes)
      a = attachment_obj_with_context(@course2)
      a.update_attribute(:size, 3.decimal_megabytes)
      a = attachment_obj_with_context(@course5)
      a.update_attribute(:size, 11.decimal_megabytes)
      a = attachment_obj_with_context(@course5)
      a.update_attribute(:size, 1.decimal_megabytes)
      a = attachment_obj_with_context(@course4)
      a.update_attribute(:size, 4.6521.decimal_megabytes)
      a = attachment_obj_with_context(@course5)
      a.update_attribute(:size, 80.decimal_megabytes)
      child = attachment_obj_with_context(@course1)
      child.update_attribute(:size, 80.decimal_megabytes)
      child.root_attachment_id = a.id
      child.save!
    end

    it "adds up storage for courses" do
      parsed = read_report(@report, { account: @account, order: "skip", header: true })
      expect(parsed.length).to eq 5
      headers = parsed.shift
      expect(headers.length).to eq parsed[0].length
      expect(parsed).to match_array [
        [@course1.id.to_s,
         "SIS_COURSE_ID_1",
         "ENG101",
         "English 101",
         @sub_account.id.to_s,
         "sub1",
         "Math",
         "1.23",
         "81.23"],
        [@course3.id.to_s,
         "SIS_COURSE_ID_3",
         "SCI101",
         "Science 101",
         @account.id.to_s,
         nil,
         @account.name,
         "0.0",
         "0.0"],
        [@course5.id.to_s,
         nil,
         "Tal101",
         "talking 101",
         @account.id.to_s,
         nil,
         @account.name,
         "92.0",
         "92.0"],
        [@course4.id.to_s,
         nil,
         "self",
         "self help",
         @account.id.to_s,
         nil,
         @account.name,
         "4.65",
         "4.65"]
      ]
    end

    it "adds up storage for courses in sub account" do
      parsed = read_report(@report, { account: @sub_account })
      expect(parsed.length).to eq 1
      expect(parsed[0]).to eq [@course1.id.to_s,
                               "SIS_COURSE_ID_1",
                               "ENG101",
                               "English 101",
                               @sub_account.id.to_s,
                               "sub1",
                               "Math",
                               "1.23",
                               "81.23"]
    end
  end
end
