require 'rubygems'
require 'bundler/setup'

require 'pry'
require 'mechanize'
require 'yaml'
require 'date'

class OSVDB
  attr_accessor :osvdb, :cve, :title, :description, :date, :cvss_v2, :gem, :url, :patched_versions, :page
  def initialize(url)
    self.url = url
    parse!
  end

  def parse!
    mech = Mechanize.new
    self.page = mech.get(url)

    page.search(".show_vuln_table").search("td ul li").each do |li|
      case li.children[0].text.strip
      when "CVE ID:"
        self.cve = li.children[1].text
      when "Vendor URL:"
        self.set_gem(li.children[1].text)
      end
    end

    self.description = page.search(".show_vuln_table").search("tr td tr .white_content p")[0].text
    self.date = page.search(".show_vuln_table").search("tr td tr .white_content tr td")[0].text
    self.title = page.search("title").text.gsub(/\d+: /, "")
    self.osvdb = page.search("title").text.match(/\d+/)[0]
    if cvss_p = page.search(".show_vuln_table").search("tr td tr .white_content div p")[0]
      self.set_cvss(cvss_p.children[0].text)
    end
  end

  def set_gem(vendortext)
    ["https://rubygems.org/gems/", "http://rubygems.org/gems/"].each do |str|
      if vendortext.match(str)
        self.gem = vendortext.gsub(str,"")
      end
    end
  end

  def set_cvss(text)
    self.cvss_v2 = text.strip.gsub("CVSSv2 Base Score = ", "")
  end

  def date
    Date.parse(@date)
  end

  def cvss_v2
    @cvss_v2.nil? ? nil : @cvss_v2.to_f
  end

  def gem
    @gem.nil? ? "unknown" : @gem
  end

  def to_yaml
    { 'gem' => gem,
      'cve' => cve,
      'osvdb' => osvdb.to_i,
      'url' => url,
      'title' => title,
      'date' => date,
      'description' => description,
      'cvss_v2' => cvss_v2,
      'patched_versions' => patched_versions }.to_yaml
  end

  def filename
    "OSVDB-#{osvdb}.yml"
  end

  def to_advisory!
    gems_path = File.join(File.dirname(__FILE__), "..", "gems")
    adv_path = File.absolute_path(File.join(gems_path, self.gem))

    FileUtils.mkdir(adv_path) unless File.exists?(adv_path)
    File.open(File.join(adv_path, filename), "w") do |io|
      io.puts self.to_yaml
    end
  end
end
