-- svg.lua
-- Copyright (C) 2021 by RStudio, PBC

local function call_rsvg_convert(path)
  local stem = pandoc.path.split_extension(path)
  local output = stem .. '.pdf'

  -- #8299
  -- if the output file already exists, don't reconvert
  if _quarto.file.exists(output) then
    warn("Skipping SVG conversion for " .. path .. " because output file already exists: " .. output)
    return output, false
  end

  local status, results = pcall(pandoc.pipe, "rsvg-convert", {"-f", "pdf", "-a", "-o", output, path}, "")
  if status then
    return output, true
  end

  if results['command'] == nil then
    -- command not found
    fail("Could not convert a SVG to a PDF for output. Please ensure that rsvg-convert is available on the path.")
  else
    fail("Could not convert a SVG to a PDF for output. An error occurred while attempting to run rsvg-convert.\nError code " .. tostring(results['error_code']) )
  end
end

local function convert_svg(image)
  -- If the src is pointing to a local file that is an svg, process it
  local ext = select(2, pandoc.path.split_extension(image.src))
  if ext ~= '.svg' then
    return nil
  end

  if not option("use-rsvg-convert", true) then
    local stem = pandoc.path.split_extension(image.src)
    local output = stem .. '.pdf'
    if not _quarto.file.exists(output) then
      warn("Skipping SVG conversion for " .. image.src .. " because use-rsvg-convert is false, but required PDF file does not exist: " .. output)
      return nil
    else
      image.src = output
      return image
    end
  end

  local converted_path, must_clean = call_rsvg_convert(image.src)
  if converted_path == nil then
    return nil
  end

  local contents = _quarto.file.read(converted_path)
  assert(contents ~= nil)
  local relative_path = pandoc.path.make_relative(converted_path, '.')
  -- add to media bag and remove the converted file
  pandoc.mediabag.insert(relative_path, 'application/pdf', contents)
  if must_clean then
    _quarto.file.remove(relative_path)
  end
  image.src = relative_path
  return image
end

function pdfImages() 
  if not quarto.doc.is_format("pdf") then
    return {}
  end
  return {
    -- convert SVG images to PDF when rendering PDFS
    Image = function(image)
      if _quarto.file.exists(image.src) then
        return convert_svg(image)
      end

      -- See if the path points to an SVG in the media bag
      -- (been generated by a filter, for example)
      return _quarto.modules.mediabag.with_mediabag_contents(image.src, function (mime_type, tempPath)
        if mime_type == 'image/svg+xml' then
          local convertedPath = call_rsvg_convert(tempPath)
          if convertedPath == nil then
            return nil
          end
          -- compute the correct relative path to the newly created file
          local mbPath = pandoc.path.make_relative(convertedPath, tmpdir, false)
          local mbContents = _quarto.file.read(convertedPath)
          assert(mbContents ~= nil)
          
          -- place the new file in the mediabag, remove the old
          pandoc.mediabag.insert(mbPath, 'application/pdf', mbContents)
          pandoc.mediabag.delete(filename)

          -- don't need to clean up the file 
          -- returned by call_rsvg_convert since it's in a temp directory

          -- update the path
          image.src = mbPath
          return image
        elseif mt == nil then
          return _quarto.modules.mediabag.resolve_image_from_url(image)
        end
      end)
    end
  }
end


