def lpad($len; $fill): 
  tostring | ($len - length) as $l | ($fill * $l)[:$l] + .;

# Severity Enum: https://github.com/nerdypepper/statix/blob/d324490e45bcda1b664f28b6f88da8580deda76b/lib/src/lib.rs#L21
# Warn/Error/Hint
def severity_or_unknown($severity):
  if 
    (["Warn","Error","Hint"] | any(index($severity))) 
  then 
    $severity 
  else "Unknown" end;

def severity_or_unknown: severity_or_unknown(.);


# Emulating how the fancy stderr displays messages
# https://github.com/nerdypepper/statix/blob/d324490e45bcda1b664f28b6f88da8580deda76b/bin/src/traits.rs#L112
def severity_to_inital($severity):
  {"Warn": "W", "Error": "E", "Hint": "I"} as $mapping |
    ($mapping).[$severity]
  // debug("severity '\($severity)' could not be be matched to an initial");

def severity_to_inital: severity_to_inital(.);

# Emulating how fancy stderr via ariadne & how errfmt displays 
# https://github.com/nerdypepper/statix/blob/d324490e45bcda1b664f28b6f88da8580deda76b/bin/src/traits.rs#L62
def severity_to_name($severity):
  {
    "Warn": "Warning", 
    "Error", 
    "Hint": "Advice",
    "Unknown"
  } as $mapping | ($mapping).[$severity];

def severity_to_tag($severity; $code):
  ($code | lpad(2; "0")) as $code |
  if $severity != "Unknown" 
    then "[\(severity_to_inital($severity))\($code)]"
    else "[\($code)?]"
  end;

def print_diagnostic($filename; $report; $issue; $diagnostic):
  $diagnostic.at.from as $from |
  $from.line as $line |
  $from.column as $column |
  severity_or_unknown($issue.severity) as $severity |
  severity_to_name($severity) as $severity_name |
  severity_to_tag($severity; $issue.code) as $severity_tag |
    "\($filename):\($line):\($column): \($severity_tag) \($severity_name): \($issue.note)";

def process_input:
  . as $root |
  .file as $filename |
  .report as $report | 
  $report[] as $issue |
  $issue.diagnostics[] as $diagnostic | 
    print_diagnostic($filename; $report; $issue; $diagnostic);

def process_inputs:
  . as $inputs |
  if length == 0 or (. == null) then halt else 
    [$inputs | .[] | process_input] | join("\n") | .+"\n" | halt_error(1)
  end;

def main: 
  [try input catch infinite] | .[0] | if isinfinite then halt else ., inputs | process_inputs end;
  #|
  #if 
  #  isempty(.) or (. == null)
  #then debug("x") else (. | process_input) end;