# frozen_string_literal: true

#
# Copyright (C) 2011 - 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 CC
  module ModuleMeta
    def create_module_meta(document = nil)
      return nil unless @course.context_modules.not_deleted.count > 0

      if document
        meta_file = nil
        rel_path = nil
      else
        meta_file = File.new(File.join(@canvas_resource_dir, CCHelper::MODULE_META), "w")
        rel_path = File.join(CCHelper::COURSE_SETTINGS_DIR, CCHelper::MODULE_META)
        document = Builder::XmlMarkup.new(target: meta_file, indent: 2)
      end

      module_id_map = {}
      document.instruct!
      document.modules(
        "xmlns" => CCHelper::CANVAS_NAMESPACE,
        "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
        "xsi:schemaLocation" => "#{CCHelper::CANVAS_NAMESPACE} #{CCHelper::XSD_URI}"
      ) do |mods_node|
        @course.context_modules.not_deleted.each do |cm|
          # context modules are in order and a pre-req can only reference
          # a previous module, so just adding as we go is okay
          mod_migration_id = create_key(cm)
          module_id_map[cm.id] = mod_migration_id

          unless export_object?(cm)
            # if the whole module isn't selected, check to see if a specific item is selected, and make sure that item gets exported
            cm.content_tags.not_deleted.each do |ct|
              if export_object?(ct) && !["ContextModuleSubHeader", "ExternalUrl"].member?(ct.content_type) && ct.content
                add_item_to_export(ct.content)
              end
            end
            next
          end

          add_exported_asset(cm)

          mods_node.module(identifier: mod_migration_id) do |m_node|
            m_node.title cm.name
            m_node.workflow_state cm.workflow_state
            m_node.position cm.position
            m_node.unlock_at CCHelper.ims_datetime(cm.unlock_at) if cm.unlock_at
            m_node.require_sequential_progress cm.require_sequential_progress.to_s unless cm.require_sequential_progress.nil?
            m_node.requirement_count cm.requirement_count if cm.requirement_count
            m_node.locked cm.locked_for?(@user).present?

            if cm.prerequisites.present?
              m_node.prerequisites do |pre_reqs|
                cm.prerequisites.each do |pre_req|
                  pre_reqs.prerequisite(type: pre_req[:type]) do |pr|
                    pr.title pre_req[:name]
                    pr.identifierref module_id_map[pre_req[:id]]
                  end
                end
              end
            end

            ct_id_map = {}
            new_quizzes_common_cartridge_enabled = Account.site_admin.feature_enabled?(:new_quizzes_common_cartridge)

            m_node.items do |items_node|
              cm.content_tags.not_deleted.each do |ct|
                ct_migration_id = create_key(ct)
                ct_id_map[ct.id] = ct_migration_id
                items_node.item(identifier: ct_migration_id) do |item_node|
                  unless ["ContextModuleSubHeader", "ExternalUrl"].member? ct.content_type
                    add_item_to_export(ct.content)
                  end

                  is_new_quiz = ct.content.instance_of?(Assignment) && ct.content.quiz_lti?
                  if is_new_quiz && new_quizzes_common_cartridge_enabled && @for_common_cartridge
                    item_node.content_type Quizzes::Quiz.to_s
                  else
                    item_node.content_type ct.content_type
                  end
                  item_node.workflow_state ct.workflow_state
                  item_node.title ct.title
                  item_node.identifierref create_key(ct.content_or_self) unless ct.content_type == "ContextModuleSubHeader"
                  if ct.content_type == "ContextExternalTool"
                    item_node.url ct.url
                    if ct.content && ct.content.context != @course
                      item_node.global_identifierref ct.content.id
                    end
                    if ct.associated_asset.instance_of?(Lti::ResourceLink)
                      item_node.lti_resource_link_lookup_uuid ct.associated_asset.lookup_uuid
                    end
                  end
                  item_node.url ct.url if ct.content_type == "ExternalUrl"
                  item_node.position ct.position
                  item_node.new_tab ct.new_tab
                  item_node.indent ct.indent
                  item_node.link_settings_json ct.link_settings.to_json
                end
              end
            end

            if cm.completion_requirements.present?
              m_node.completionRequirements do |crs_node|
                cm.completion_requirements.each do |c_req|
                  crs_node.completionRequirement(type: c_req[:type]) do |cr_node|
                    cr_node.min_score c_req[:min_score] unless c_req[:min_score].blank?
                    cr_node.min_percentage c_req[:min_percentage] unless c_req[:min_percentage].blank?
                    cr_node.identifierref ct_id_map[c_req[:id]]
                  end
                end
              end
            end
          end
        end
      end
      meta_file&.close
      rel_path
    end
  end
end
