# frozen_string_literal: true

# TODO: remove this class when we no longer need to support legacy
# clair-scanner data. See https://gitlab.com/gitlab-org/gitlab/issues/35442
module Gitlab
  module Ci
    module Parsers
      module Security
        module Formatters
          class DeprecatedFormattedContainerScanningVulnerability
            def initialize(vulnerability)
              @vulnerability = vulnerability
            end

            def message
              @message ||= format_definitions(
                %w[vulnerability featurename] => '%{vulnerability} in %{featurename}',
                'vulnerability' => '%{vulnerability}'
              )
            end

            def description
              @description ||= format_definitions(
                'description' => '%{description}',
                %w[featurename featureversion] => '%{featurename}:%{featureversion} is affected by %{vulnerability}',
                'featurename' => '%{featurename} is affected by %{vulnerability}',
                'namespace' => '%{namespace} is affected by %{vulnerability}'
              )
            end

            def severity
              raw_severity = vulnerability['severity']

              @severity ||= case raw_severity
                            when 'Negligible'
                              'low'
                            when 'Unknown', 'Low', 'Medium', 'High', 'Critical'
                              raw_severity.downcase
                            when 'Defcon1'
                              'critical'
                            else
                              safe_severity = ERB::Util.html_escape(raw_severity)
                              raise(
                                ::Gitlab::Ci::Parsers::Security::Common::SecurityReportParserError,
                                "Unknown severity in container scanning report: #{safe_severity}"
                              )
                            end
            end

            def solution
              @solution ||= format_definitions(
                %w[fixedby featurename featureversion] => 'Upgrade %{featurename} from %{featureversion} to %{fixedby}',
                %w[fixedby featurename] => 'Upgrade %{featurename} to %{fixedby}',
                'fixedby' => 'Upgrade to %{fixedby}'
              )
            end

            def cve
              @cve ||= vulnerability['vulnerability']
            end

            def operating_system
              @operating_system ||= vulnerability['namespace']
            end

            def package_name
              @package_name ||= vulnerability['featurename']
            end

            def version
              @version ||= vulnerability['featureversion']
            end

            def url
              @url ||= vulnerability['link']
            end

            private

            attr_reader :vulnerability

            def format_definitions(definitions)
              find_definitions(definitions).then do |_, value|
                if value.present?
                  value % vulnerability.symbolize_keys
                end
              end
            end

            def find_definitions(definitions)
              definitions.find do |keys, value|
                vulnerability.values_at(*keys).all?(&:present?)
              end
            end
          end
        end
      end
    end
  end
end
