# frozen_string_literal: true

module Types
  class VulnerabilityType < BaseObject
    graphql_name 'Vulnerability'
    description 'Represents a vulnerability.'

    authorize :read_vulnerability

    expose_permissions Types::PermissionTypes::Vulnerability

    field :id, GraphQL::ID_TYPE, null: false,
          description: 'GraphQL ID of the vulnerability'

    field :title, GraphQL::STRING_TYPE, null: true,
          description: 'Title of the vulnerability'

    field :description, GraphQL::STRING_TYPE, null: true,
          description: 'Description of the vulnerability'

    field :state, VulnerabilityStateEnum, null: true,
          description: "State of the vulnerability (#{::Vulnerability.states.keys.join(', ').upcase})"

    field :severity, VulnerabilitySeverityEnum, null: true,
          description: "Severity of the vulnerability (#{::Vulnerabilities::Finding::SEVERITY_LEVELS.keys.join(', ').upcase})"

    field :report_type, VulnerabilityReportTypeEnum, null: true,
          description: "Type of the security report that found the vulnerability (#{::Vulnerabilities::Finding::REPORT_TYPES.keys.join(', ').upcase})"

    field :resolved_on_default_branch, GraphQL::BOOLEAN_TYPE, null: false,
          description: "Indicates whether the vulnerability is fixed on the default branch or not"

    field :user_notes_count, GraphQL::INT_TYPE, null: false,
          description: 'Number of user notes attached to the vulnerability',
          resolve: -> (obj, _args, ctx) {
            ::Gitlab::Graphql::Aggregations::Vulnerabilities::LazyUserNotesCountAggregate.new(ctx, obj)
          }

    field :vulnerability_path, GraphQL::STRING_TYPE, null: true,
          description: "URL to the vulnerability's details page",
          resolve: -> (obj, _args, _ctx) { ::Gitlab::Routing.url_helpers.project_security_vulnerability_path(obj.project, obj) }

    field :issue_links, ::Types::Vulnerability::IssueLinkType.connection_type, null: false,
          description: "List of issue links related to the vulnerability",
          resolver: Resolvers::Vulnerabilities::IssueLinksResolver

    field :location, VulnerabilityLocationType, null: true,
          description: 'Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability',
          resolve: -> (obj, _args, _ctx) { obj.finding&.location&.merge(report_type: obj.report_type) }

    field :scanner, VulnerabilityScannerType, null: true,
          description: 'Scanner metadata for the vulnerability.',
          resolve: -> (obj, _args, _ctx) do
            Representation::VulnerabilityScannerEntry.new(obj.finding&.scanner, obj.report_type)
          end

    field :primary_identifier, VulnerabilityIdentifierType, null: true,
          description: 'Primary identifier of the vulnerability.',
          resolve: -> (obj, _args, _ctx) { obj.finding&.primary_identifier }

    field :identifiers, [VulnerabilityIdentifierType], null: false,
          description: 'Identifiers of the vulnerability.',
          resolve: -> (obj, _args, _ctx) { obj.finding&.identifiers }

    field :project, ::Types::ProjectType, null: true,
          description: 'The project on which the vulnerability was found',
          authorize: :read_project,
          resolve: -> (obj, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, obj.project_id).find }
  end
end
