class Inspec::Resources::Podman

def containers

def containers
  PodmanContainerFilter.new(parse_containers)
end

def ensure_keys(entry, labels)

def ensure_keys(entry, labels)
  labels.each do |key|
    entry[key.downcase] = nil unless entry.key?(key.downcase)
  end
  entry
end

def images

def images
  PodmanImageFilter.new(parse_images)
end

def info

def info
  return @info if defined?(@info)
  sub_cmd = "info --format json"
  output = run_command(sub_cmd)
  @info = Hashie::Mash.new(JSON.parse(output))
rescue JSON::ParserError => _e
  Hashie::Mash.new({})
end

def networks

def networks
  PodmanNetworkFilter.new(parse_networks)
end

def object(id)

returns information about podman objects
def object(id)
  return @inspect if defined?(@inspect)
  output = run_command("inspect #{id} --format json")
  data = JSON.parse(output)
  data = data[0] if data.is_a?(Array)
  @inspect = Hashie::Mash.new(data)
rescue JSON::ParserError => _e
  Hashie::Mash.new({})
end

def parse(content)

Returns: Parsed data.
Method to parse JDON content.
def parse(content)
  require "json" unless defined?(JSON)
  output = JSON.parse(content)
  parsed_output = []
  output.each do |entry|
    entry = entry.map do |k, v|
      [k.downcase, v]
    end.to_h
    parsed_output << entry
  end
  parsed_output
rescue => e
  raise Inspec::Exceptions::ResourceFailed, "Unable to parse command JSON output: #{e.message}"
end

def parse_containers

Returns the parsed command output.
Calls the run_command method to get all podman containers and parse the command output.
def parse_containers
  labels = %w{ID Image ImageID Command CreatedAt RunningFor Status Pod Ports Size Names Networks Labels Mounts}
  parse_json_command(labels, "ps -a --no-trunc --size")
end

def parse_images

Returns the parsed command output.
Calls the run_command method to get all podman images and parse the command output.
def parse_images
  labels = %w{ID Repository Tag Size Digest CreatedAt CreatedSince History}
  parse_json_command(labels, "images -a --no-trunc")
end

def parse_json_command(labels, subcommand)

def parse_json_command(labels, subcommand)
  # build command
  format = labels.map { |label| "\"#{label}\": {{json .#{label}}}" }
  raw = inspec.command("podman #{subcommand} --format '{#{format.join(", ")}}'").stdout
  output = []
  raw.each_line do |entry|
    # convert all keys to lower_case to work well with ruby and filter table
    row = JSON.parse(entry).map do |key, value|
      [key.downcase, value]
    end.to_h
    # ensure all keys are there
    row = ensure_keys(row, labels)
    output.push(row)
  end
  output
rescue JSON::ParserError => _e
  warn "Could not parse `podman #{subcommand}` output"
  []
end

def parse_networks

Returns the parsed command output.
Calls the run_command method to get all podman network list and parse the command output.
def parse_networks
  labels = %w{ID Name Driver Labels Options IPAMOptions Created Internal IPv6Enabled DNSEnabled NetworkInterface Subnets}
  parse_json_command(labels, "network ls --no-trunc")
end

def parse_pods

Returns the parsed command output.
Calls the run_command method to get all podman pod list and parse the command output.
def parse_pods
  sub_cmd = "pod ps --no-trunc --format json"
  output = run_command(sub_cmd)
  parse(output)
end

def parse_volumes

Returns the parsed command output.
Calls the run_command method to get all podman volume list and parse the command output.
def parse_volumes
  sub_cmd = "volume ls --format json"
  output = run_command(sub_cmd)
  parse(output)
end

def pods

def pods
  PodmanPodFilter.new(parse_pods)
end

def run_command(subcommand)

Returns the command output or raises the command execution error.
Runs the given podman command on the host machine on which podman is installed
def run_command(subcommand)
  result = inspec.command("podman #{subcommand}")
  if result.stderr.empty?
    result.stdout
  else
    raise "Error while running command \'podman #{subcommand}\' : #{result.stderr}"
  end
end

def to_s

def to_s
  "Podman"
end

def version

def version
  return @version if defined?(@version)
  sub_cmd = "version --format json"
  output = run_command(sub_cmd)
  @version = Hashie::Mash.new(JSON.parse(output))
rescue JSON::ParserError => _e
  Hashie::Mash.new({})
end

def volumes

def volumes
  PodmanVolumeFilter.new(parse_volumes)
end