{.push raises: [].}

import std/posix

import ../protocol/lcgi

{.passc: "-I" & currentSourcePath().untilLast('/').}

{.push header: """
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h"
""".}
proc stbir_resize_uint8_srgb(input_pixels: ptr uint8;
  input_w, input_h, input_stride_in_bytes: cint; output_pixels: ptr uint8;
  output_w, output_h, output_stride_in_bytes, num_channels, alpha_channel,
  flags: cint): cint {.importc.}
{.pop.}

proc main() =
  var srcWidth = cint(-1)
  var srcHeight = cint(-1)
  var dstWidth = cint(-1)
  var dstHeight = cint(-1)
  for hdr in getEnvEmpty("REQUEST_HEADERS").split('\n'):
    let k = hdr.until(':')
    let v = hdr.after(':').strip()
    case k
    of "Cha-Image-Target-Dimensions":
      (dstWidth, dstHeight) = parseDimensionsC(v, allowZero = false)
    of "Cha-Image-Dimensions":
      (srcWidth, srcHeight) = parseDimensionsC(v, allowZero = false)
  let ps = newPosixStream(STDIN_FILENO)
  let os = newPosixStream(STDOUT_FILENO)
  let src = ps.readLoopOrMmap(int(srcWidth * srcHeight * 4))
  let dst = os.maybeMmapForSend(int(dstWidth * dstHeight * 4 + 1))
  if src == nil or dst == nil:
    cgiDie(ceInternalError, "failed to open i/o")
  dst.p[0] = uint8('\n') # for CGI
  enterNetworkSandbox()
  doAssert stbir_resize_uint8_srgb(addr src.p[0], srcWidth, srcHeight, 0,
    addr dst.p[1], dstWidth, dstHeight, 0, 4, 3, 0) != 0
  discard os.writeLoop(dst)
  deallocMem(src)
  deallocMem(dst)

main()

{.pop.} # raises: []
