require 'rubygems'
require 'time'

module HolePicker
  class Vulnerability
    NEW_VULNERABILITY_DAYS = 7
    NEW_VULNERABILITY_TIME = NEW_VULNERABILITY_DAYS * 86400

    attr_reader :id, :date, :url, :note, :gems

    def self.next_id
      @@count ||= 0
      @@count += 1
    end

    def initialize(json)
      @gems = {}

      json['gems'].each do |name, versions|
        @gems[name] = versions.map { |v| ::Gem::Version.new(v) }
      end

      @id = self.class.next_id
      @url = json['url']
      @note = json['note']
      @date = Time.parse(json['date'])
    end

    def day
      @date.strftime("%Y-%m-%d")
    end

    def recent?
      date > Time.now - NEW_VULNERABILITY_TIME
    end

    def tag
      "##{@id}"
    end

    def gem_names
      @gems.keys
    end

    def gem_vulnerable?(gem)
      !gem_safe?(gem)
    end

    def gem_safe?(gem)
      fixes = @gems[gem.name]
      !fixes || fixes.any? { |fix| fix_included?(fix, gem) } || fixes.all? { |fix| gem.version > fix }
    end


    private

    def fix_included?(fix, gem)
      gem.version == fix || (gem.version > fix && same_level?(fix, gem))
    end

    def same_level?(fix, gem)
      segments_count = fix.segments.length

      fix.segments[0...segments_count-1] == gem.version.segments[0...segments_count-1]
    end
  end
end
