class Inspec::Resources::Processes

def build_process_list(command, regex, field_map)

def build_process_list(command, regex, field_map)
  cmd = inspec.command(command)
  all = cmd.stdout.split("\n")[1..-1]
  return [] if all.nil?
  # map all the process lines into match objects, fetch the available fields,
  # and then build an OpenStruct of the process data for each process
  all.map do |line|
    line = line.match(regex)
    # skip this line if we couldn't match the regular expression
    next if line.nil?
    # skip this entry if there's no command for this line
    next if line[field_map[:command]].nil?
    # build a hash of process data that we'll turn into a struct for FilterTable
    process_data = {}
    [:label, :pid, :cpu, :mem, :vsz, :rss, :tty, :stat, :start, :time, :user, :command].each do |param|
      # not all operating systems support all fields, so skip the field if we don't have it
      process_data[param] = line[field_map[param]] if field_map.key?(param)
    end
    # ensure pid, vsz, and rss are integers for backward compatibility
    [:pid, :vsz, :rss].each do |int_param|
      process_data[int_param] = process_data[int_param].to_i if process_data.key?(int_param)
    end
    # strip any newlines off the command
    process_data[:command].strip!
    # return an OpenStruct of the process for future use by FilterTable
    OpenStruct.new(process_data)
  end.compact
end

def busybox_ps?

def busybox_ps?
  @busybox_ps ||= inspec.command('ps --help').stderr.include?('BusyBox')
end

def exists?

def exists?
  !@list.empty?
end

def filtered_processes

def filtered_processes
  @list
end

def initialize(grep = /.*/)

def initialize(grep = /.*/)
  @grep = grep
  # turn into a regexp if it isn't one yet
  if grep.class == String
    # if windows ignore case as we can't make up our minds
    if inspec.os.windows?
      grep = '(?i)' + grep
    else
      grep = '(/[^/]*)*' + grep unless grep[0] == '/'
      grep = '^' + grep + '(\s|$)'
    end
    grep = Regexp.new(grep)
  end
  all_cmds = ps_axo
  @list = all_cmds.find_all do |hm|
    hm[:command] =~ grep
  end
end

def list

def list
  warn '[DEPRECATION] `processes.list` is deprecated. Please use `processes.entries` instead. It will be removed in version 2.0.0.'
  @list
end

def ps_axo

def ps_axo
  os = inspec.os
  if os.linux?
    command, regex, field_map = ps_configuration_for_linux
  elsif os.windows?
    command = '$Proc = Get-Process -IncludeUserName | Where-Object {$_.Path -ne $null } | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")'
    # Wanted to use /(?:^|,)([^,]*)/; works on rubular.com not sure why here?
    regex = /^(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+)$/
    field_map = {
      pid: 2,
      cpu: 3,
      mem: 4,
      vsz: 5,
      rss: 6,
      tty: 7,
      stat: 8,
      start: 9,
      time: 10,
      user: 11,
      command: 12,
    }
  else
    command = 'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command'
    regex = /^\s*([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
    field_map = {
      pid: 1,
      cpu: 2,
      mem: 3,
      vsz: 4,
      rss: 5,
      tty: 6,
      stat: 7,
      start: 8,
      time: 9,
      user: 10,
      command: 11,
    }
  end
  build_process_list(command, regex, field_map)
end

def ps_configuration_for_linux

def ps_configuration_for_linux
  if busybox_ps?
    command = 'ps -o pid,vsz,rss,tty,stat,time,ruser,args'
    regex = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/
    field_map = {
      pid: 1,
      vsz: 2,
      rss: 3,
      tty: 4,
      stat: 5,
      time: 6,
      user: 7,
      command: 8,
    }
  else
    command = 'ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command'
    regex = /^(.+?)\s+(\d+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(\w{3} \d{2}|\d{2}:\d{2}:\d{2})\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
    field_map = {
      label: 1,
      pid: 2,
      cpu: 3,
      mem: 4,
      vsz: 5,
      rss: 6,
      tty: 7,
      stat: 8,
      start: 9,
      time: 10,
      user: 11,
      command: 12,
    }
  end
  [command, regex, field_map]
end

def to_s

def to_s
  "Processes #{@grep.class == String ? @grep : @grep.inspect}"
end