module Analysis

	##
	# Class to hold a summary of the vulnerabilities.
	# 
	# @highs            - list of high-severity vulnerabilities 
	# @mediums          - list of medium-severity vulnerabilities 
	# @lows             - list of low-severity vulnerabilities
	# high_count        - Number of high-severity vulnerabilities
	# medium_count      - Number of medium-severity vulnerabilities
	# low_count         - Number of low-severity vulnerabilities
    # high_rule_count   - Number of high-severity, overly permissive rules
	# medium_rule_count - Number of medium-severity, overly permissive rules 
	# low_rule_count    - Number of low-severity, overly permissive rules 
	class Summary
		attr_accessor :highs, :mediums, :lows

		def initialize(highs, mediums, lows)
			@highs = highs
			@mediums = mediums
			@lows = lows
		end

		##
		# Count the number of high vulnerbilities and return the count
		def high_count
			return count_vulns(@highs)
		end

		##
		# Count the number of medium vulnerbilities and return the count
		def medium_count
			return count_vulns(@mediums)
		end

		##
		# Count the number of low vulnerbilities and return the count
		def low_count
			return count_vulns(@lows)
		end

		##
		# Count the number of high-severity, overly permissive rules and 
		# return the count. 
		def high_rule_count
			return count_permissive_rules(@highs)
		end

		# Count the number of high-severity, overly permissive rules and 
		# return the count. 
		def medium_rule_count
			return count_permissive_rules(@mediums)
		end

		# Count the number of low-severity, overly permissive rules and 
		# return the count. 
		def low_rule_count
			return count_permissive_rules(@lows)
		end

		##
		# Input: A list of Analyze::Vulnerability objects
		#
		# Output: An integer representing the number of items affected by the 
		# vulnerability.
		#
		# Action: Loop through each vulnerability and add up the length of the 
		# list of affected items.
		def count_vulns(vulns)

			count = 0
	
			unless vulns.empty?
				vulns.each do |vuln|
					# List contains a header row so need to subtract 1
					count += vuln.affected.length - 1 
				end
			end

			return count

		end

		##
		# Input: A list of Analyze::Vulnerability objects
		#
		# Output: An integer representing the number of items affected by 
		# "Overly Permissive Rules".
		#
		# Action: Loop through each vulnerability and find the rule named 
		# "Overly Permissive Rules" and return the length of the list of 
		# affected items.
		def count_permissive_rules(vulns)

			count = 0
	
			unless vulns.empty?
				vulns.each do |vuln|
					if vuln.name == "Overly Permissive Rules"
						# List contains a header row so need to subtract 1
						count += vuln.affected.length - 1
					end 
				end
			end

			return count

		end

	end


	##
	# Class to hold a Vulnerabilities.
	# 
	# @name     - name of the vulnerability 
	# @severity - severity level: high, medium, low 
	# @desc     - description of the vulnerability
	# @solution - recommended solution for the vulnerability
	# @affected - list of items affected by the vulnerability. The first item 
	#             in the list is the column names used when writing the list 
	#             in the report 
	class Vulnerability
		attr_accessor :name, :severity, :desc, :solution, :affected

		def initialize(name)
			@name = name
			@severity = nil
			@desc = nil
			@solution = nil
			@affected = []
		end

		##
		# The vulnerability check is expected to set @severity to 'high', 
		# 'medium', or 'low'. Anything else raises an error.
		def severity=(input)
			if ((input == 'high') || (input == 'medium') || (input == 'low'))
				@severity = input
			else
				raise AnalyzeError.new("Invalid input for Analyze::Vulnerabilty.severity: #{input}")
			end
		end
	
	end

end
