/* Copyright Krzysztof Kowalczyk 2006-2007
   Copyright Hib Eris <hib@hiberis.nl> 2008, 2013
   Copyright 2018, 2020, 2022 Albert Astals Cid <aacid@kde.org> 2018
   Copyright 2019 Oliver Sander <oliver.sander@tu-dresden.de>
   Copyright 2020 Adam Reichold <adam.reichold@t-online.de>
   License: GPLv2 */
/*
  A tool to stress-test poppler rendering and measure rendering times for
  very simplistic performance measuring.

  TODO:
   * make it work with cairo output as well
   * print more info about document like e.g. enumerate images,
     streams, compression, encryption, password-protection. Each should have
     a command-line arguments to turn it on/off
   * never over-write file given as -out argument (optionally, provide -force
     option to force writing the -out file). It's way too easy too lose results
     of a previous run.
*/

#ifdef _MSC_VER
// this sucks but I don't know any other way
#    pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

#include <config.h>

#ifdef _WIN32
#    include <windows.h>
#else
#    include <strings.h>
#endif

// Define COPY_FILE if you want the file to be copied to a local disk first
// before it's tested. This is desired if a file is on a slow drive.
// Currently copying only works on Windows.
// Not enabled by default.
// #define COPY_FILE 1

#include <cassert>
#include <cstdio>
#include <cstdarg>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <ctime>

#ifdef HAVE_DIRENT_H
#    include <dirent.h>
#endif

#include "Error.h"
#include "ErrorCodes.h"
#include "goo/GooString.h"
#include "goo/GooTimer.h"
#include "GlobalParams.h"
#include "splash/SplashBitmap.h"
#include "Object.h" /* must be included before SplashOutputDev.h because of sloppiness in SplashOutputDev.h */
#include "SplashOutputDev.h"
#include "TextOutputDev.h"
#include "PDFDoc.h"
#include "Link.h"

#ifdef _MSC_VER
#    define strdup _strdup
#    define strcasecmp _stricmp
#endif

#define dimof(X) (sizeof(X) / sizeof((X)[0]))

#define INVALID_PAGE_NO -1

/* Those must be implemented in order to provide preview during execution.
   They can be no-ops. An implementation for windows is in
   perf-test-preview-win.cc
*/
extern void PreviewBitmapInit();
extern void PreviewBitmapDestroy();
extern void PreviewBitmapSplash(SplashBitmap *bmpSplash);

class PdfEnginePoppler
{
public:
    PdfEnginePoppler();
    ~PdfEnginePoppler();

    PdfEnginePoppler(const PdfEnginePoppler &) = delete;
    PdfEnginePoppler &operator=(const PdfEnginePoppler &) = delete;

    const char *fileName() const { return _fileName; };

    void setFileName(const char *fileName)
    {
        assert(!_fileName);
        _fileName = (char *)strdup(fileName);
    }

    int pageCount() const { return _pageCount; }

    bool load(const char *fileName);
    SplashBitmap *renderBitmap(int pageNo, double zoomReal, int rotation);

    SplashOutputDev *outputDevice();

private:
    char *_fileName;
    int _pageCount;

    PDFDoc *_pdfDoc;
    SplashOutputDev *_outputDev;
};

typedef struct StrList
{
    struct StrList *next;
    char *str;
} StrList;

/* List of all command-line arguments that are not switches.
   We assume those are:
     - names of PDF files
     - names of a file with a list of PDF files
     - names of directories with PDF files
*/
static StrList *gArgsListRoot = nullptr;

/* Names of all command-line switches we recognize */
#define TIMINGS_ARG "-timings"
#define RESOLUTION_ARG "-resolution"
#define RECURSIVE_ARG "-recursive"
#define OUT_ARG "-out"
#define PREVIEW_ARG "-preview"
#define SLOW_PREVIEW_ARG "-slowpreview"
#define LOAD_ONLY_ARG "-loadonly"
#define PAGE_ARG "-page"
#define TEXT_ARG "-text"

/* Should we record timings? True if -timings command-line argument was given. */
static bool gfTimings = false;

/* If true, we use render each page at resolution 'gResolutionX'/'gResolutionY'.
   If false, we render each page at its native resolution.
   True if -resolution NxM command-line argument was given. */
static bool gfForceResolution = false;
static int gResolutionX = 0;
static int gResolutionY = 0;
/* If NULL, we output the log info to stdout. If not NULL, should be a name
   of the file to which we output log info.
   Controlled by -out command-line argument. */
static char *gOutFileName = nullptr;
/* FILE * corresponding to gOutFileName or stdout if gOutFileName is NULL or
   was invalid name */
static FILE *gOutFile = nullptr;
/* FILE * corresponding to gOutFileName or stderr if gOutFileName is NULL or
   was invalid name */
static FILE *gErrFile = nullptr;

/* If True and a directory is given as a command-line argument, we'll process
   pdf files in sub-directories as well.
   Controlled by -recursive command-line argument */
static bool gfRecursive = false;

/* If true, preview rendered image. To make sure that they're being rendered correctly. */
static bool gfPreview = false;

/* 1 second (1000 milliseconds) */
#define SLOW_PREVIEW_TIME 1000

/* If true, preview rendered image in a slow mode i.e. delay displaying for
   SLOW_PREVIEW_TIME. This is so that a human has enough time to see if the
   PDF renders ok. In release mode on fast processor pages take only ~100-200 ms
   to render and they go away too quickly to be inspected by a human. */
static bool gfSlowPreview = false;

/* If true, we only dump the text, not render */
static bool gfTextOnly = false;

#define PAGE_NO_NOT_GIVEN -1

/* If equals PAGE_NO_NOT_GIVEN, we're in default mode where we render all pages.
   If different, will only render this page */
static int gPageNo = PAGE_NO_NOT_GIVEN;
/* If true, will only load the file, not render any pages. Mostly for
   profiling load time */
static bool gfLoadOnly = false;

#define PDF_FILE_DPI 72

#define MAX_FILENAME_SIZE 1024

/* DOS is 0xd 0xa */
#define DOS_NEWLINE "\x0d\x0a"
/* Mac is single 0xd */
#define MAC_NEWLINE "\x0d"
/* Unix is single 0xa (10) */
#define UNIX_NEWLINE "\x0a"
#define UNIX_NEWLINE_C 0xa

static void memzero(void *data, size_t len)
{
    memset(data, 0, len);
}

static void *zmalloc(size_t len)
{
    void *data = malloc(len);
    if (data) {
        memzero(data, len);
    }
    return data;
}

/* Concatenate 4 strings. Any string can be NULL.
   Caller needs to free() memory. */
static char *str_cat4(const char *str1, const char *str2, const char *str3, const char *str4)
{
    char *str;
    char *tmp;
    size_t str1_len = 0;
    size_t str2_len = 0;
    size_t str3_len = 0;
    size_t str4_len = 0;

    if (str1) {
        str1_len = strlen(str1);
    }
    if (str2) {
        str2_len = strlen(str2);
    }
    if (str3) {
        str3_len = strlen(str3);
    }
    if (str4) {
        str4_len = strlen(str4);
    }

    str = (char *)zmalloc(str1_len + str2_len + str3_len + str4_len + 1);
    if (!str) {
        return nullptr;
    }

    tmp = str;
    if (str1) {
        memcpy(tmp, str1, str1_len);
        tmp += str1_len;
    }
    if (str2) {
        memcpy(tmp, str2, str2_len);
        tmp += str2_len;
    }
    if (str3) {
        memcpy(tmp, str3, str3_len);
        tmp += str3_len;
    }
    if (str4) {
        memcpy(tmp, str4, str1_len);
    }
    return str;
}

static char *str_dup(const char *str)
{
    return str_cat4(str, nullptr, nullptr, nullptr);
}

static bool str_eq(const char *str1, const char *str2)
{
    if (!str1 && !str2) {
        return true;
    }
    if (!str1 || !str2) {
        return false;
    }
    if (0 == strcmp(str1, str2)) {
        return true;
    }
    return false;
}

static bool str_ieq(const char *str1, const char *str2)
{
    if (!str1 && !str2) {
        return true;
    }
    if (!str1 || !str2) {
        return false;
    }
    if (0 == strcasecmp(str1, str2)) {
        return true;
    }
    return false;
}

static bool str_endswith(const char *txt, const char *end)
{
    size_t end_len;
    size_t txt_len;

    if (!txt || !end) {
        return false;
    }

    txt_len = strlen(txt);
    end_len = strlen(end);
    if (end_len > txt_len) {
        return false;
    }
    if (str_eq(txt + txt_len - end_len, end)) {
        return true;
    }
    return false;
}

/* TODO: probably should move to some other file and change name to
   sleep_milliseconds */
static void sleep_milliseconds(int milliseconds)
{
#ifdef _WIN32
    Sleep((DWORD)milliseconds);
#else
    struct timespec tv;
    int secs, nanosecs;
    secs = milliseconds / 1000;
    nanosecs = (milliseconds - (secs * 1000)) * 1000;
    tv.tv_sec = (time_t)secs;
    tv.tv_nsec = (long)nanosecs;
    while (true) {
        int rval = nanosleep(&tv, &tv);
        if (rval == 0) {
            /* Completed the entire sleep time; all done. */
            return;
        } else if (errno == EINTR) {
            /* Interrupted by a signal. Try again. */
            continue;
        } else {
            /* Some other error; bail out. */
            return;
        }
    }
    return;
#endif
}

static SplashColorMode gSplashColorMode = splashModeBGR8;

static SplashColor splashColRed;
static SplashColor splashColGreen;
static SplashColor splashColBlue;
static SplashColor splashColWhite;
static SplashColor splashColBlack;

#define SPLASH_COL_RED_PTR (SplashColorPtr) & (splashColRed[0])
#define SPLASH_COL_GREEN_PTR (SplashColorPtr) & (splashColGreen[0])
#define SPLASH_COL_BLUE_PTR (SplashColorPtr) & (splashColBlue[0])
#define SPLASH_COL_WHITE_PTR (SplashColorPtr) & (splashColWhite[0])
#define SPLASH_COL_BLACK_PTR (SplashColorPtr) & (splashColBlack[0])

static SplashColorPtr gBgColor = SPLASH_COL_WHITE_PTR;

static void splashColorSet(SplashColorPtr col, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
{
    switch (gSplashColorMode) {
    case splashModeBGR8:
        col[0] = blue;
        col[1] = green;
        col[2] = red;
        break;
    case splashModeRGB8:
        col[0] = red;
        col[1] = green;
        col[2] = blue;
        break;
    default:
        assert(0);
        break;
    }
}

static void SplashColorsInit()
{
    splashColorSet(SPLASH_COL_RED_PTR, 0xff, 0, 0, 0);
    splashColorSet(SPLASH_COL_GREEN_PTR, 0, 0xff, 0, 0);
    splashColorSet(SPLASH_COL_BLUE_PTR, 0, 0, 0xff, 0);
    splashColorSet(SPLASH_COL_BLACK_PTR, 0, 0, 0, 0);
    splashColorSet(SPLASH_COL_WHITE_PTR, 0xff, 0xff, 0xff, 0);
}

PdfEnginePoppler::PdfEnginePoppler() : _fileName(nullptr), _pageCount(INVALID_PAGE_NO), _pdfDoc(nullptr), _outputDev(nullptr) { }

PdfEnginePoppler::~PdfEnginePoppler()
{
    free(_fileName);
    delete _outputDev;
    delete _pdfDoc;
}

bool PdfEnginePoppler::load(const char *fileName)
{
    setFileName(fileName);

    _pdfDoc = new PDFDoc(std::make_unique<GooString>(fileName));
    if (!_pdfDoc->isOk()) {
        return false;
    }
    _pageCount = _pdfDoc->getNumPages();
    return true;
}

SplashOutputDev *PdfEnginePoppler::outputDevice()
{
    if (!_outputDev) {
        bool bitmapTopDown = true;
        _outputDev = new SplashOutputDev(gSplashColorMode, 4, false, gBgColor, bitmapTopDown);
        if (_outputDev) {
            _outputDev->startDoc(_pdfDoc);
        }
    }
    return _outputDev;
}

SplashBitmap *PdfEnginePoppler::renderBitmap(int pageNo, double zoomReal, int rotation)
{
    assert(outputDevice());
    if (!outputDevice()) {
        return nullptr;
    }

    double hDPI = (double)PDF_FILE_DPI * zoomReal * 0.01;
    double vDPI = (double)PDF_FILE_DPI * zoomReal * 0.01;
    bool useMediaBox = false;
    bool crop = true;
    bool doLinks = true;
    _pdfDoc->displayPage(_outputDev, pageNo, hDPI, vDPI, rotation, useMediaBox, crop, doLinks, nullptr, nullptr);

    SplashBitmap *bmp = _outputDev->takeBitmap();
    return bmp;
}

static int StrList_Len(StrList **root)
{
    int len = 0;
    StrList *cur;
    assert(root);
    if (!root) {
        return 0;
    }
    cur = *root;
    while (cur) {
        ++len;
        cur = cur->next;
    }
    return len;
}

static int StrList_InsertAndOwn(StrList **root, char *txt)
{
    StrList *el;
    assert(root && txt);
    if (!root || !txt) {
        return false;
    }

    el = (StrList *)malloc(sizeof(StrList));
    if (!el) {
        return false;
    }
    el->str = txt;
    el->next = *root;
    *root = el;
    return true;
}

static int StrList_Insert(StrList **root, char *txt)
{
    char *txtDup;

    assert(root && txt);
    if (!root || !txt) {
        return false;
    }
    txtDup = str_dup(txt);
    if (!txtDup) {
        return false;
    }

    if (!StrList_InsertAndOwn(root, txtDup)) {
        free((void *)txtDup);
        return false;
    }
    return true;
}

static void StrList_FreeElement(StrList *el)
{
    if (!el) {
        return;
    }
    free((void *)el->str);
    free((void *)el);
}

static void StrList_Destroy(StrList **root)
{
    StrList *cur;
    StrList *next;

    if (!root) {
        return;
    }
    cur = *root;
    while (cur) {
        next = cur->next;
        StrList_FreeElement(cur);
        cur = next;
    }
    *root = nullptr;
}

static void my_error(ErrorCategory, Goffset pos, const char *msg)
{
#if 0
    char        buf[4096], *p = buf;

    // NB: this can be called before the globalParams object is created
    if (globalParams && globalParams->getErrQuiet()) {
        return;
    }

    if (pos >= 0) {
      p += _snprintf(p, sizeof(buf)-1, "Error (%lld): ", (long long)pos);
        *p   = '\0';
        OutputDebugString(p);
    } else {
        OutputDebugString("Error: ");
    }

    p = buf;
    p += vsnprintf(p, sizeof(buf) - 1, msg, args);
    while ( p > buf  &&  isspace(p[-1]) )
            *--p = '\0';
    *p++ = '\r';
    *p++ = '\n';
    *p   = '\0';
    OutputDebugString(buf);

    if (pos >= 0) {
        p += _snprintf(p, sizeof(buf)-1, "Error (%lld): ", (long long)pos);
        *p   = '\0';
        OutputDebugString(buf);
        if (gErrFile)
            fprintf(gErrFile, buf);
    } else {
        OutputDebugString("Error: ");
        if (gErrFile)
            fprintf(gErrFile, "Error: ");
    }
#endif
#if 0
    p = buf;
    va_start(args, msg);
    p += vsnprintf(p, sizeof(buf) - 3, msg, args);
    while ( p > buf  &&  isspace(p[-1]) )
            *--p = '\0';
    *p++ = '\r';
    *p++ = '\n';
    *p   = '\0';
    OutputDebugString(buf);
    if (gErrFile)
        fprintf(gErrFile, buf);
    va_end(args);
#endif
}

static void LogInfo(const char *fmt, ...) GCC_PRINTF_FORMAT(1, 2);

static void LogInfo(const char *fmt, ...)
{
    va_list args;
    char buf[4096], *p = buf;

    p = buf;
    va_start(args, fmt);
    p += vsnprintf(p, sizeof(buf) - 1, fmt, args);
    *p = '\0';
    fprintf(gOutFile, "%s", buf);
    va_end(args);
    fflush(gOutFile);
}

static void PrintUsageAndExit(int argc, char **argv)
{
    printf("Usage: pdftest [-preview|-slowpreview] [-loadonly] [-timings] [-text] [-resolution NxM] [-recursive] [-page N] [-out out.txt] pdf-files-to-process\n");
    for (int i = 0; i < argc; i++) {
        printf("i=%d, '%s'\n", i, argv[i]);
    }
    exit(0);
}

static bool ShowPreview()
{
    if (gfPreview || gfSlowPreview) {
        return true;
    }
    return false;
}

static void RenderPdfAsText(const char *fileName)
{
    PDFDoc *pdfDoc = nullptr;
    GooString *txt = nullptr;
    int pageCount;
    double timeInMs;

    assert(fileName);
    if (!fileName) {
        return;
    }

    LogInfo("started: %s\n", fileName);

    TextOutputDev *textOut = new TextOutputDev(nullptr, true, 0, false, false);
    if (!textOut->isOk()) {
        delete textOut;
        return;
    }

    GooTimer msTimer;
    pdfDoc = new PDFDoc(std::make_unique<GooString>(fileName));
    if (!pdfDoc->isOk()) {
        error(errIO, -1, "RenderPdfFile(): failed to open PDF file {0:s}\n", fileName);
        goto Exit;
    }

    msTimer.stop();
    timeInMs = msTimer.getElapsed();
    LogInfo("load: %.2f ms\n", timeInMs);

    pageCount = pdfDoc->getNumPages();
    LogInfo("page count: %d\n", pageCount);

    for (int curPage = 1; curPage <= pageCount; curPage++) {
        if ((gPageNo != PAGE_NO_NOT_GIVEN) && (gPageNo != curPage)) {
            continue;
        }

        msTimer.start();
        int rotate = 0;
        bool useMediaBox = false;
        bool crop = true;
        bool doLinks = false;
        pdfDoc->displayPage(textOut, curPage, 72, 72, rotate, useMediaBox, crop, doLinks);
        txt = textOut->getText(0.0, 0.0, 10000.0, 10000.0);
        msTimer.stop();
        timeInMs = msTimer.getElapsed();
        if (gfTimings) {
            LogInfo("page %d: %.2f ms\n", curPage, timeInMs);
        }
        printf("%s\n", txt->c_str());
        delete txt;
        txt = nullptr;
    }

Exit:
    LogInfo("finished: %s\n", fileName);
    delete textOut;
    delete pdfDoc;
}

#ifdef _MSC_VER
#    define POPPLER_TMP_NAME "c:\\poppler_tmp.pdf"
#else
#    define POPPLER_TMP_NAME "/tmp/poppler_tmp.pdf"
#endif

static void RenderPdf(const char *fileName)
{
    const char *fileNameSplash = nullptr;
    PdfEnginePoppler *engineSplash = nullptr;
    int pageCount;
    double timeInMs;

#ifdef COPY_FILE
    // TODO: fails if file already exists and has read-only attribute
    CopyFile(fileName, POPPLER_TMP_NAME, false);
    fileNameSplash = POPPLER_TMP_NAME;
#else
    fileNameSplash = fileName;
#endif
    LogInfo("started: %s\n", fileName);

    engineSplash = new PdfEnginePoppler();

    GooTimer msTimer;
    if (!engineSplash->load(fileNameSplash)) {
        LogInfo("failed to load splash\n");
        goto Error;
    }
    msTimer.stop();
    timeInMs = msTimer.getElapsed();
    LogInfo("load splash: %.2f ms\n", timeInMs);
    pageCount = engineSplash->pageCount();

    LogInfo("page count: %d\n", pageCount);
    if (gfLoadOnly) {
        goto Error;
    }

    for (int curPage = 1; curPage <= pageCount; curPage++) {
        if ((gPageNo != PAGE_NO_NOT_GIVEN) && (gPageNo != curPage)) {
            continue;
        }

        SplashBitmap *bmpSplash = nullptr;

        GooTimer msRenderTimer;
        bmpSplash = engineSplash->renderBitmap(curPage, 100.0, 0);
        msRenderTimer.stop();
        timeInMs = msRenderTimer.getElapsed();
        if (gfTimings) {
            if (!bmpSplash) {
                LogInfo("page splash %d: failed to render\n", curPage);
            } else {
                LogInfo("page splash %d (%dx%d): %.2f ms\n", curPage, bmpSplash->getWidth(), bmpSplash->getHeight(), timeInMs);
            }
        }

        if (ShowPreview()) {
            PreviewBitmapSplash(bmpSplash);
            if (gfSlowPreview) {
                sleep_milliseconds(SLOW_PREVIEW_TIME);
            }
        }
        delete bmpSplash;
    }
Error:
    delete engineSplash;
    LogInfo("finished: %s\n", fileName);
}

static void RenderFile(const char *fileName)
{
    if (gfTextOnly) {
        RenderPdfAsText(fileName);
        return;
    }

    RenderPdf(fileName);
}

static bool ParseInteger(const char *start, const char *end, int *intOut)
{
    char numBuf[16];
    int digitsCount;
    const char *tmp;

    assert(start && end && intOut);
    assert(end >= start);
    if (!start || !end || !intOut || (start > end)) {
        return false;
    }

    digitsCount = 0;
    tmp = start;
    while (tmp <= end) {
        if (isspace(*tmp)) {
            /* do nothing, we allow whitespace */
        } else if (!isdigit(*tmp)) {
            return false;
        }
        numBuf[digitsCount] = *tmp;
        ++digitsCount;
        if (digitsCount == dimof(numBuf) - 3) { /* -3 to be safe */
            return false;
        }
        ++tmp;
    }
    if (0 == digitsCount) {
        return false;
    }
    numBuf[digitsCount] = 0;
    *intOut = atoi(numBuf);
    return true;
}

/* Given 'resolutionString' in format NxM (e.g. "100x200"), parse the string and put N
   into 'resolutionXOut' and M into 'resolutionYOut'.
   Return false if there was an error (e.g. string is not in the right format */
static bool ParseResolutionString(const char *resolutionString, int *resolutionXOut, int *resolutionYOut)
{
    const char *posOfX;

    assert(resolutionString);
    assert(resolutionXOut);
    assert(resolutionYOut);
    if (!resolutionString || !resolutionXOut || !resolutionYOut) {
        return false;
    }
    *resolutionXOut = 0;
    *resolutionYOut = 0;
    posOfX = strchr(resolutionString, 'X');
    if (!posOfX) {
        posOfX = strchr(resolutionString, 'x');
    }
    if (!posOfX) {
        return false;
    }
    if (posOfX == resolutionString) {
        return false;
    }
    if (!ParseInteger(resolutionString, posOfX - 1, resolutionXOut)) {
        return false;
    }
    if (!ParseInteger(posOfX + 1, resolutionString + strlen(resolutionString) - 1, resolutionYOut)) {
        return false;
    }
    return true;
}

static void ParseCommandLine(int argc, char **argv)
{
    char *arg;

    if (argc < 2) {
        PrintUsageAndExit(argc, argv);
    }

    for (int i = 1; i < argc; i++) {
        arg = argv[i];
        assert(arg);
        if ('-' == arg[0]) {
            if (str_ieq(arg, TIMINGS_ARG)) {
                gfTimings = true;
            } else if (str_ieq(arg, RESOLUTION_ARG)) {
                ++i;
                if (i == argc) {
                    PrintUsageAndExit(argc, argv); /* expect a file name after that */
                }
                if (!ParseResolutionString(argv[i], &gResolutionX, &gResolutionY)) {
                    PrintUsageAndExit(argc, argv);
                }
                gfForceResolution = true;
            } else if (str_ieq(arg, RECURSIVE_ARG)) {
                gfRecursive = true;
            } else if (str_ieq(arg, OUT_ARG)) {
                /* expect a file name after that */
                ++i;
                if (i == argc) {
                    PrintUsageAndExit(argc, argv);
                }
                gOutFileName = str_dup(argv[i]);
            } else if (str_ieq(arg, PREVIEW_ARG)) {
                gfPreview = true;
            } else if (str_ieq(arg, TEXT_ARG)) {
                gfTextOnly = true;
            } else if (str_ieq(arg, SLOW_PREVIEW_ARG)) {
                gfSlowPreview = true;
            } else if (str_ieq(arg, LOAD_ONLY_ARG)) {
                gfLoadOnly = true;
            } else if (str_ieq(arg, PAGE_ARG)) {
                /* expect an integer after that */
                ++i;
                if (i == argc) {
                    PrintUsageAndExit(argc, argv);
                }
                gPageNo = atoi(argv[i]);
                if (gPageNo < 1) {
                    PrintUsageAndExit(argc, argv);
                }
            } else {
                /* unknown option */
                PrintUsageAndExit(argc, argv);
            }
        } else {
            /* we assume that this is not an option hence it must be
               a name of PDF/directory/file with PDF names */
            StrList_Insert(&gArgsListRoot, arg);
        }
    }
}

static bool IsPdfFileName(char *path)
{
    if (str_endswith(path, ".pdf")) {
        return true;
    }
    return false;
}

/* Render 'cmdLineArg', which can be:
   - name of PDF file
*/
static void RenderCmdLineArg(char *cmdLineArg)
{
    assert(cmdLineArg);
    if (!cmdLineArg) {
        return;
    }
    if (IsPdfFileName(cmdLineArg)) {
        RenderFile(cmdLineArg);
    } else {
        error(errCommandLine, -1, "unexpected argument '{0:s}'", cmdLineArg);
    }
}

int main(int argc, char **argv)
{
    setErrorCallback(my_error);
    ParseCommandLine(argc, argv);
    if (0 == StrList_Len(&gArgsListRoot)) {
        PrintUsageAndExit(argc, argv);
    }
    assert(gArgsListRoot);

    SplashColorsInit();
    globalParams = std::make_unique<GlobalParams>();
    if (!globalParams) {
        return 1;
    }
    globalParams->setErrQuiet(false);

    FILE *outFile = nullptr;
    if (gOutFileName) {
        outFile = fopen(gOutFileName, "wb");
        if (!outFile) {
            printf("failed to open -out file %s\n", gOutFileName);
            return 1;
        }
        gOutFile = outFile;
    } else {
        gOutFile = stdout;
    }

    if (gOutFileName) {
        gErrFile = outFile;
    } else {
        gErrFile = stderr;
    }

    PreviewBitmapInit();

    StrList *curr = gArgsListRoot;
    while (curr) {
        RenderCmdLineArg(curr->str);
        curr = curr->next;
    }
    if (outFile) {
        fclose(outFile);
    }
    PreviewBitmapDestroy();
    StrList_Destroy(&gArgsListRoot);
    free(gOutFileName);
    return 0;
}
