<commit_before>#
# Copyright (C) 2010-2016 dtk contributors
#
# This file is part of the dtk project.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
module DTK
  class Assembly::Instance
    class Violation
      def table_form
        type_and_display
      end

      # must be overwritten
      def hash_form
        fail Error, "Missing method '#{self.class}#hash_form'"
      end
      # could be overwritten
      def type
        Aux.underscore(Aux.demodulize(self.class.to_s)).to_sym
      end

      private

      def attr_display_name(attr, print_level = :component)
        attr.print_form(Opts.new(level: print_level, convert_node_component: true))[:display_name]
      end

      def hash_form_aux(hash)
        hash.inject(type_and_display) { |h, (k, v)| v.nil? ? h : h.merge(k => v) }
      end

      def attribute_ref
        attr_display_name(@attr, @print_level)
      end

      def type_and_display
        { type: type, description: description }
      end

      class ReqUnsetAttr < self
        def initialize(attr, print_level)
          @attr        = attr
          @print_level = print_level
        end

        def type
          :required_unset_attribute
        end

        def hash_form
          hash_form_aux(attribute_ref: attribute_ref)
        end

        def description
          "Attribute (#{attr_display_name(@attr, @print_level)}) is required, but unset"
        end
      end

      class ReqUnsetAttrs < self
        def initialize(attrs, print_level)
          opts_print = Opts.new(level: print_level)
          @attr_display_names = attrs.map { |attr| attr_display_name(attr, print_level) }
        end

        def type
          :required_unset_attributes
        end

        def description
          aug_attrs_print_form = @attr_display_names.join(', ')
          "At least one of the attributes (#{aug_attrs_print_form}) is required to be set"
        end
      end

      class IllegalAttrValue < self
        # opts can have keys
        #  legal_values
        def initialize(attr, value, opts = {})
          @attr         = attr
          @value        = value
          @legal_values = opts[:legal_values]
        end

        def type
          :illegal_attribute_value
        end

        def hash_form
          hash_form_aux(attribute_ref: attribute_ref, value: @value, legal_values: @legal_values)
        end

        def description
          ret = "Attribute '#{attr_display_name(@attr)}' has illegal value '#{@value}'"
          ret << "; legal values are: #{@legal_values.join(', ')}" if @legal_values
          ret
        end
      end


      class TargetServiceCmpsMissing < self
        def initialize(component_types)
          @component_types = component_types
        end
        
        def type
          :target_service_cmps_missing
        end
        
        def description<commit_msg>DTK-2525: Added attributes that indicate how to fix violation<commit_after>#
# Copyright (C) 2010-2016 dtk contributors
#
# This file is part of the dtk project.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
module DTK
  class Assembly::Instance
    class Violation
      def table_form
        type_and_display
      end

      # must be overwritten
      def hash_form
        fail Error, "Missing method '#{self.class}#hash_form'"
      end

      private

      def initialize(opts = {})
        # TODO: stub for datatype checking
        @datatype = opts[:datatype]
      end

      def attr_display_name(attr, print_level = :component)
        attr.print_form(Opts.new(level: print_level, convert_node_component: true))[:display_name]
      end

      def hash_form_aux(hash)
        hash.inject(type_and_display.merge(fix_action: fix_action, fix_text: fix_text)) do |h, (k, v)| 
          # This will remove nil values from hash
          v.nil? ? h : h.merge(k => v)
        end
      end

      def attribute_ref
        attr_display_name(@attr, @print_level)
      end

      def type_and_display
        { type: type, description: description }
      end

      # could be overwritten
      def type
        Aux.underscore(Aux.demodulize(self.class.to_s)).to_sym
      end

      # must be overwritten
      def fix_action
        fail Error, "Missing method '#{self.class}#fix_action'"
      end
      def fix_text
        fail Error, "Missing method '#{self.class}#fix_text'"
      end

      ########## Violation classes
      class ReqUnsetAttr < self
        def initialize(attr, print_level)
          super()
          @attr              = attr
          @print_level       = print_level
          @attr_display_name = attr_display_name(attr, print_level)
        end

        def type
          :required_unset_attribute
        end

        def hash_form
          hash_form_aux(attribute_ref: attribute_ref)
        end

        def fix_action
          :set_attribute
        end

        def fix_text
          "Enter value for attribute '#{@attr_display_name}'"
        end

        def description
          "Attribute '#{@attr_display_name}' is required, but unset"
        end
      end

      class IllegalAttrValue < self
        # opts can have keys
        #  legal_values
        def initialize(attr, value, opts = {})
          super()
          @attr              = attr
          @attr_display_name = attr_display_name(attr)
          @value             = value
          @legal_values      = opts[:legal_values]
        end

        def type
          :illegal_attribute_value
        end

        def fix_action
          :set_attribute
        end

        def fix_text
          "Enter value for attribute '#{@attr_display_name}'"
        end

        def hash_form
          hash_form_aux(attribute_ref: attribute_ref, value: @value, legal_values: @legal_values)
        end

        def description
          ret = "Attribute '#{@attr_display_name}' has illegal value '#{@value}'"
          ret << "; legal values are: #{@legal_values.join(', ')}" if @legal_values
          ret
        end
      end

      # TODO: DTK-2525; got here in refining the violations to work with fix wizard

      class ReqUnsetAttrs < self
        def initialize(attrs, print_level)
          opts_print = Opts.new(level: print_level)
          @attr_display_names = attrs.map { |attr| attr_display_name(attr, print_level) }
        end

        def type
          :required_unset_attributes
        end

        def description
          aug_attrs_print_form = @attr_display_names.join(', ')
          "At least one of the attributes (#{aug_attrs_print_form}) is required to be set"
        end
      end


      class TargetServiceCmpsMissing < self
        def initialize(component_types)
          @component_types = component_types
        end
        
        def type
          :target_service_cmps_missing
        end
        
        def description
{'fraction_non_alphanumeric': 0.07348446255731024, 'fraction_numerical': 0.004075394803871625, 'mean_word_length': 2.108867775138559, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '2759936', 'n_tokens_mistral': 2225, 'n_tokens_neox': 2159, 'n_words': 665}