/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "qrcode-util.h"

#if HAVE_QRENCODE
#include <qrencode.h>

#include "dlfcn-util.h"
#include "locale-util.h"
#include "log.h"
#include "terminal-util.h"

#define ANSI_WHITE_ON_BLACK "\033[40;37;1m"

static void *qrcode_dl = NULL;

static QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) = NULL;
static void (*sym_QRcode_free)(QRcode *qrcode) = NULL;

int dlopen_qrencode(void) {
        return dlopen_many_sym_or_warn(
                        &qrcode_dl, "libqrencode.so.4", LOG_DEBUG,
                        DLSYM_ARG(QRcode_encodeString),
                        DLSYM_ARG(QRcode_free));
}

static void print_border(FILE *output, unsigned width) {
        /* Four rows of border */
        for (unsigned y = 0; y < 4; y += 2) {
                fputs(ANSI_WHITE_ON_BLACK, output);

                for (unsigned x = 0; x < 4 + width + 4; x++)
                        fputs("\342\226\210", output);

                fputs(ANSI_NORMAL "\n", output);
        }
}

static void write_qrcode(FILE *output, QRcode *qr) {
        assert(qr);

        if (!output)
                output = stdout;

        print_border(output, qr->width);

        for (unsigned y = 0; y < (unsigned) qr->width; y += 2) {
                const uint8_t *row1 = qr->data + qr->width * y;
                const uint8_t *row2 = row1 + qr->width;

                fputs(ANSI_WHITE_ON_BLACK, output);
                for (unsigned x = 0; x < 4; x++)
                        fputs("\342\226\210", output);

                for (unsigned x = 0; x < (unsigned) qr->width; x++) {
                        bool a, b;

                        a = row1[x] & 1;
                        b = (y+1) < (unsigned) qr->width ? (row2[x] & 1) : false;

                        if (a && b)
                                fputc(' ', output);
                        else if (a)
                                fputs("\342\226\204", output);
                        else if (b)
                                fputs("\342\226\200", output);
                        else
                                fputs("\342\226\210", output);
                }

                for (unsigned x = 0; x < 4; x++)
                        fputs("\342\226\210", output);
                fputs(ANSI_NORMAL "\n", output);
        }

        print_border(output, qr->width);
        fflush(output);
}

int print_qrcode(FILE *out, const char *header, const char *string) {
        QRcode* qr;
        int r;

        /* If this is not an UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
         * codes */
        if (!is_locale_utf8() || !colors_enabled())
                return -EOPNOTSUPP;

        r = dlopen_qrencode();
        if (r < 0)
                return r;

        qr = sym_QRcode_encodeString(string, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
        if (!qr)
                return -ENOMEM;

        if (header)
                fprintf(out, "\n%s:\n\n", header);

        write_qrcode(out, qr);

        fputc('\n', out);

        sym_QRcode_free(qr);
        return 0;
}
#endif
