<commit_before>module Seek
  module Api
    ##
    # A class to convert JSON-API-structured parameters into a form that SEEK's controllers understand.
    # Four stages of conversion:
    # 1. De-serialize - The JSON-API parameters are converted into a Rails-esque form: params['data_file'] = { ... }
    # 1. Convert - Certain parameter values are converted according to the `CONVERSIONS` mapping between keys and procs.
    # 3. Rename - Keys the above form are renamed according to the `RENAME` mapping below.
    # 4. Elevate - Parameters in the `ELEVATE` list are moved up out of e.g. `params['data_file']` into the top-level `params`

    class ParameterConverter
      # Custom conversions required on certain parameters to fit how the controller expects.
      CONVERSIONS = {
          policy: ->(value) {
            value[:access_type] = PolicyHelper::key_access_type(value.delete(:access))
            perms = {}
            (value.delete(:permissions) || []).each_with_index do |permission, index|
              perms[index.to_s] = {
                  access_type: PolicyHelper::key_access_type(permission[:access]),
                  contributor_type: permission[:resource_type].singularize.classify,
                  contributor_id: permission[:resource_id],
              }
            end
            value[:permissions_attributes] = perms

            value
          },

          content_blobs: ->(value) {
            (value || []).map do |cb|
              cb[:data_url] = cb.delete(:url)
              cb
            end
          },

          creator_ids: ->(value) {
            value.map { |id| ['', id.to_i] }.to_json
          },

          publication_ids: ->(value) {
            value.map { |id| "#{id}," }
          },

          assay_class: ->(value) {
            if value && value[:key]
              AssayClass.find_by(key: value[:key])
            end
          },

          assay_type: ->(value) {
            value[:uri]
          },

          technology_type: ->(value) {
            value[:uri]
          },

          tags: ->(value) {
            value.join(', ')
          },

          programme_ids: ->(value) {
            value.try(:first)
          }
      }

      # Parameters to rename
      RENAME = {
          tags: :tag_list,
          policy: :policy_attributes,
          creator_ids: :creators,
          publication_ids: :related_publication_ids,
          assay_class: :assay_class_id,
          assay_type: :assay_type_uri,
          technology_type: :technology_type_uri,
          programme_ids: :programme_id
      }

      # Parameters to "elevate" out of params[bla] to the top-level.
      ELEVATE = %i[assay_organism_ids tag_list expertise_list tool_list policy_attributes content_blobs
       assay_ids related_publication_ids revision_comments creators]

      def initialize(controller_name)
        @controller_name = controller_name
      end

      def convert(parameters)
        @parameters = parameters

        # Step 1
        @parameters[@<EMAIL>] =
            ActiveModelSerializers::Deserialization.jsonapi_parse(@parameters)

        # Step 2
        convert_parameters

        # Step 3
        rename_parameters

        # Step 4
        elevate_parameters

        @parameters.delete(:data)

        @parameters
      end

      private

      def convert_parameters<commit_msg>Freeze constants. Comments<commit_after>module Seek
  module Api
    ##
    # A class to convert JSON-API-structured parameters into a form that SEEK's controllers understand.
    # Four stages of conversion:
    # 1. De-serialize - The JSON-API parameters are converted into a Rails-esque form: params['data_file'] = { ... }
    # 1. Convert - Certain parameter values are converted according to the `CONVERSIONS` mapping between keys and procs.
    # 3. Rename - Keys the above form are renamed according to the `RENAME` mapping below.
    # 4. Elevate - Parameters in the `ELEVATE` list are moved up out of e.g. `params['data_file']` into the top-level `params`
    class ParameterConverter
      # Custom conversions required on certain parameters to fit how the controller expects.
      CONVERSIONS = {
          policy: ->(value) {
            value[:access_type] = PolicyHelper::key_access_type(value.delete(:access))
            perms = {}
            (value.delete(:permissions) || []).each_with_index do |permission, index|
              perms[index.to_s] = {
                  access_type: PolicyHelper::key_access_type(permission[:access]),
                  contributor_type: permission[:resource_type].singularize.classify,
                  contributor_id: permission[:resource_id],
              }
            end
            value[:permissions_attributes] = perms

            value
          },

          content_blobs: ->(value) {
            (value || []).map do |cb|
              cb[:data_url] = cb.delete(:url)
              cb
            end
          },

          creator_ids: ->(value) {
            value.map { |id| ['', id.to_i] }.to_json
          },

          publication_ids: ->(value) {
            value.map { |id| "#{id}," }
          },

          assay_class: ->(value) {
            if value && value[:key]
              AssayClass.find_by(key: value[:key])
            end
          },

          assay_type: ->(value) {
            value[:uri]
          },

          technology_type: ->(value) {
            value[:uri]
          },

          tags: ->(value) {
            value.join(', ')
          },

          programme_ids: ->(value) {
            value.try(:first)
          }
      }.freeze

      # Parameters to rename
      RENAME = {
          tags: :tag_list,
          policy: :policy_attributes,
          creator_ids: :creators,
          publication_ids: :related_publication_ids,
          assay_class: :assay_class_id,
          assay_type: :assay_type_uri,
          technology_type: :technology_type_uri,
          programme_ids: :programme_id
      }.freeze

      # Parameters to "elevate" out of params[bla] to the top-level.
      ELEVATE = %i[assay_organism_ids tag_list expertise_list tool_list policy_attributes content_blobs
       assay_ids related_publication_ids revision_comments creators].freeze

      def initialize(controller_name)
        @controller_name = controller_name
      end

      def convert(parameters)
        @parameters = parameters

        # Step 1 - JSON-API -> Rails format
        @parameters[@<EMAIL>] =
            ActiveModelSerializers::Deserialization.jsonapi_parse(@parameters)

        # Step 2 - Perform any conversions on parameter values
        convert_parameters

        # Step 3 - Rename any parameter keys
        rename_parameters

        # Step 4 - Move any parameters into top-level
        elevate_parameters

        @parameters.delete(:data)

        @parameters
      end

      private

      def convert_parameters
{'fraction_non_alphanumeric': 0.09720815854187762, 'fraction_numerical': 0.0023144799652828007, 'mean_word_length': 1.9026028547439127, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 24, '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': '230035', 'n_tokens_mistral': 1947, 'n_tokens_neox': 1841, 'n_words': 473}