# frozen_string_literal: true

module WPScan
  # Vulnerability model.
  class Vulnerability
    include References

    attr_reader :title, :type, :fixed_in, :introduced_in, :cvss, :poc, :uuid

    # @param [ String ] title
    # @param [ Hash ] references
    # @option references [ Array<String>, String ] :cve
    # @option references [ Array<String>, String ] :secunia
    # @option references [ Array<String>, String ] :osvdb
    # @option references [ Array<String>, String ] :exploitdb
    # @option references [ Array<String> ] :url URL(s) to related advisories etc
    # @option references [ Array<String>, String ] :metasploit The related metasploit module(s)
    # @option references [ Array<String> ] :youtube
    # @param [ String ] type
    # @param [ String ] fixed_in
    # @param [ String ] introduced_in
    # @param [ HashSymbol ] cvss
    # @option cvss [ String ] :score
    # @option cvss [ String ] :vector
    # rubocop:disable Metrics/ParameterLists
    def initialize(title, references: {}, type: nil, fixed_in: nil, introduced_in: nil, cvss: nil, poc: nil, uuid: nil)
      # rubocop:enable Metrics/ParameterLists
      @title         = title
      @type          = type
      @fixed_in      = fixed_in
      @introduced_in = introduced_in
      @cvss          = { score: cvss[:score], vector: cvss[:vector] } if cvss
      @poc           = poc
      @uuid          = uuid

      self.references = references
    end

    # @param [ Hash ] json_data
    # @return [ Vulnerability ]
    def self.load_from_json(json_data)
      references = { wpvulndb: json_data['id'].to_s }

      if json_data['references']
        references_keys.each do |key|
          references[key] = json_data['references'][key.to_s] if json_data['references'].key?(key.to_s)
        end
      end

      new(
        json_data['title'],
        references: references,
        type: json_data['vuln_type'],
        fixed_in: json_data['fixed_in'],
        introduced_in: json_data['introduced_in'],
        cvss: json_data['cvss']&.symbolize_keys,
        poc: json_data['poc'],
        uuid: json_data['id'].to_s # The 'id' field IS the UUID in WPScan API
      )
    end

    # @param [ Vulnerability ] other
    #
    # @return [ Boolean ]
    def ==(other)
      title == other.title &&
        type == other.type &&
        references == other.references &&
        fixed_in == other.fixed_in &&
        cvss == other.cvss &&
        poc == other.poc &&
        uuid == other.uuid
    end
  end
end
