module XinetdParser

def parse_xinetd(raw) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
def parse_xinetd(raw) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  return {} if raw.nil?
  res = {}
  cur_group = nil
  simple_conf = []
  rest = raw + "\n"
  until rest.empty?
    # extract content line
    nl = rest.index("\n") || (rest.length-1)
    comment = rest.index('#') || (rest.length-1)
    dst_idx = comment < nl ? comment : nl
    inner_line = dst_idx == 0 ? '' : rest[0..dst_idx-1].strip
    # update unparsed content
    rest = rest[nl+1..-1]
    next if inner_line.empty?
    if inner_line == '}'
      if cur_group == 'defaults'
        res[cur_group] = SimpleConfig.new(simple_conf.join("\n"))
      else
        res[cur_group] ||= []
        res[cur_group].push(SimpleConfig.new(simple_conf.join("\n")))
      end
      cur_group = nil
    elsif rest.lstrip[0] == '{'
      cur_group = inner_line
      simple_conf = []
      rest = rest[rest.index("\n")+1..-1]
    elsif cur_group.nil?
      # parse all included files
      others = xinetd_include_dir(inner_line[/includedir (.+)/, 1])
      # complex merging of included configurations, as multiple services
      # may be defined with the same name but different configuration
      others.each { |ores|
        ores.each { |k, v|
          res[k] ||= []
          res[k].concat(v)
        }
      }
    else
      simple_conf.push(inner_line)
    end
  end
  res
end

def xinetd_include_dir(dir)

def xinetd_include_dir(dir)
  return [] if dir.nil?
  unless inspec.file(dir).directory?
    raise Inspec::Exceptions::ResourceSkipped, "Can't find folder: #{dir}"
  end
  files = inspec.command("find #{dir} -type f").stdout.split("\n")
  files.map { |file| parse_xinetd(read_content(file)) }
end