class Inspec::Resources::FirewallD

def active_zones

def active_zones
  # return syntax:
  #   [default-zone-name]
  #       interfaces: [open interfases]
  #
  # example:
  #   public
  #       interfaces: enp0s3
  firewalld_command('--get-active-zones')
end

def default_zone

def default_zone
  # return: word associated with the name of the default zone
  # example: 'public'
  firewalld_command('--get-default-zone')
end

def firewalld_command(command)

def firewalld_command(command)
  command = "firewall-cmd #{command}"
  result = inspec.command(command)
  if result.stderr != ''
    return "Error on command #{command}: #{result.stderr}"
  end
  result.stdout.strip
end

def has_port_enabled_in_zone?(query_port, query_zone = default_zone)

def has_port_enabled_in_zone?(query_port, query_zone = default_zone)
  firewalld_command("--zone=#{query_zone} --query-port=#{query_port}") == 'yes'
end

def has_rule_enabled?(rule, query_zone = default_zone)

def has_rule_enabled?(rule, query_zone = default_zone)
  rule = "rule #{rule}" unless rule.start_with?('rule')
  firewalld_command("--zone=#{query_zone} --query-rich-rule='#{rule}'") == 'yes'
end

def has_service_enabled_in_zone?(query_service, query_zone = default_zone)

def has_service_enabled_in_zone?(query_service, query_zone = default_zone)
  firewalld_command("--zone=#{query_zone} --query-service=#{query_service}") == 'yes'
end

def has_zone?(query_zone)

def has_zone?(query_zone)
  return false unless installed?
  result = firewalld_command('--get-zones').split(' ')
  result.include?(query_zone)
end

def initialize

def initialize
  @params = parse_active_zones(active_zones)
end

def installed?

def installed?
  inspec.command('firewall-cmd').exist?
end

def parse_active_zones(content)

def parse_active_zones(content)
  # Split by every second line, which contains the zone and the interfaces.
  content = content.split(/\n/).each_slice(2).map { |slice| slice.join("\n") }
  content.map do |line|
    parse_line(line)
  end.compact
end

def parse_line(line)

def parse_line(line)
  zone = line.split("\n")[0]
  {
    'zone' => zone,
    'interfaces' => line.split(':')[1].split(' '),
    'services' =>   services_bound(zone),
    'sources' =>    sources_bound(zone),
  }
end

def running?

def running?
  return false unless installed?
  result = firewalld_command('--state')
  result =~ /^running/ ? true : false
end

def service_ports_enabled_in_zone(query_service, query_zone = default_zone)

def service_ports_enabled_in_zone(query_service, query_zone = default_zone)
  # return: String of ports open
  # example: ['22/tcp', '4722/tcp']
  firewalld_command("--zone=#{query_zone} --service=#{query_service} --get-ports --permanent").split(' ')
end

def service_protocols_enabled_in_zone(query_service, query_zone = default_zone)

def service_protocols_enabled_in_zone(query_service, query_zone = default_zone)
  # return: String of protocoals open
  # example: ['icmp', 'ipv4', 'igmp']
  firewalld_command("--zone=#{query_zone} --service=#{query_service} --get-protocols --permanent").split(' ')
end

def services_bound(query_zone)

def services_bound(query_zone)
  # result: a list of services bound to a zone.
  # example: ['ssh', 'dhcpv6-client']
  firewalld_command("--zone=#{query_zone} --list-services").split(' ')
end

def sources_bound(query_zone)

def sources_bound(query_zone)
  # result: a list containing either an ip address or ip address with a mask, or a ipset or an ipset with the ipset prefix.
  # example: ['192.168.0.4', '192.168.0.0/16', '2111:DB28:ABC:12::', '2111:db89:ab3d:0112::0/64']
  firewalld_command("--zone=#{query_zone} --list-sources").split(' ')
end