#include "japi_fr_ngx.h"
#include <string>

// Для того чтобы включить вывод отладочных сообщений в консоль
// следует задать переменную среды окружения FR_DRV_DEBUG_CONSOLE=1

// пример вызова функции драйвера
// request получает указатель на строку байтов в фомате utf-8 с завершающим нулем
// request выполняет запрос и возвращает длину ответа включая заверщающий строку ноль
// response копирует ответ в формате ut8-8 с заверщающим нулем в буфер
// выделение и освобождение памяти для запроса и ответа выпололняется на стороне клиента

std::string exchange(const std::string& req)
{
    std::string resp;
    int sz = kkt_driver::request(req.c_str());
    if (sz > 0) {
        char* buf = (char*)malloc(sz);
        if (buf != nullptr) {
            if (kkt_driver::response(buf)) {
                resp = std::string(buf);
            }
            free(buf);
        }
    }
    return resp;
}

void doTest(const char req[])
{
    std::string resp = exchange(std::string(req));
}

void testConfigureDiscover()
{
    const char req[] = R"({
        "type": "configure"
    })";
    doTest(req);
}

void testConfigureMac()
{
    const char req[] = R"({
        "type": "configure",
        "uri": "serial:///dev/tty.usbmodemKKT_0000011?timeout=15000&protocol=v1&baudrate=115200"
    })";
    doTest(req);
}

void testConfigureWin()
{
    const char req[] = R"({
        "type": "configure",
        "uri": "serial://COM4?timeout=15000&protocol=v1&baudrate=115200"
    })";
    std::string resp = exchange(req);
}

void testReportX()
{
    const char req[] = R"({
        "type": "reportX",
        "password": 30,
        "operation": {
          "name": "Иванов",
          "vatin": "123654789507"
        }
    })";
    doTest(req);
}

void testOpenShift()
{
    const char req[] = R"({
        "type": "openShift",
        "password": 30,
        "operation": {
          "name": "Иванов",
          "vatin": "123654789507"
        },
        "additionalAttribute": {
            "name": "Дополнительный реквизит ООС",
            "value": "Значение"
        },
        "address": "Адрес расчетов",
        "paymentAddress": "Место расчетов",
        "electronically": false,
        "preItems": [
            { "type" : "text",
              "name" : "ОТКРЫТА НОВАЯ СМЕНА",
              "doubleWidth" : true },
            { "type" : "text",
              "name" : "ХОРОШЕГО ДНЯ, КАССИР",
              "doubleWidth" : true } ]
    })";
    doTest(req);
}

void testCloseShift()
{
    const char req[] = R"({
        "type": "closeShift",
        "password": 30,
        "operation": {
          "name": "Иванов",
          "vatin": "123654789507"
        },
        "additionalAttribute": {
            "name": "Дополнительный реквизит ООС",
            "value": "Значение"
        },
        "address": "Адрес расчетов",
        "paymentAddress": "Место расчетов",
        "electronically": false,
        "preItems": [
            { "type" : "text",
              "name" : "HELLO HEADER",
              "font": 7,
              "doubleWidth" : false,
              "doubleHeight" : false,
              "storeInJournal" : false },
            { "type" : "pixels",
              "pixels" : "AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/w==",
              "width" : 16,
              "scale" : 1 },
            { "type" : "barcode",
              "barcode" : "123456789012",
              "barcodeType" : "EAN13",
              "scale" : 2 },
            { "type" : "barcode",
              "barcode" : "https://check.egais.ru?id=cf1b1096-3cbc-11e7-b3c1-9b018b2ba3f7",
              "barcodeType" : "QR",
              "scale" : 4 } ],
        "postItems": [
            { "type" : "text",
              "text" : "HELLO FOOTER",
              "font": 7,
              "doubleWidth" : false,
              "doubleHeight" : false,
              "storeInJournal" : false } ]
    })";
    doTest(req);
}

void testSellFfd12() {
    const char req[] = R"({
        "type": "sell",
        "password": 30,
        "validateMarkingCodes": true,
        "operation": {
          "name": "Иванов",
          "vatin": ""
        },
        "agentInfo": {
           "agents": ["payingAgent", "bankPayingAgent" ],
           "payingAgent": {
              "phones": ["+79161112233"]
            },
            "receivePaymentsOperator": {
              "phones": ["+79163331122"]
            },
            "moneyTransferOperator": {
              "phones": ["+79162223311"],
              "name": "Оператор перевода",
              "address": "Улица Оператора Перевода, д.1",
              "vatin": "321456987121"
            }
        },
        "supplierInfo": {
            "name": "Поставщик",
            "vatin": "956839506500",
            "phones": ["+79162223311"]
        },
        "items": [
            { "type": "position",
              "name": "*3282705 Товар",
              "price": 299.95,
              "quantity": 1.0,
              "amount": 299.95,
              "measurementUnit": "piece",
              "infoDiscountAmount": 0.0,
              "tax": {
                "type": "vat20",
                "sum": 0.0
              },
              "paymentMethod": "fullPayment",
              "paymentObject": "commodityWithMarking",
              "imcParams": {
                  "imcType": "auto",
                  "imc": "MDE0NDk0NTUwNDM1MzA2ODIxUVhZWFNBTEdMTVlRUR05MUVFMDYdOTJZV0NYYm1LNlNOOHZ2d294WkZrN1dBWThXb0pOTUdHcjZDZ3RpdWphMDRjPQ",
                  "itemEstimatedStatus": "itemDryForSale",
                  "itemQuantity": 1,
                  "itemUnits": "piece",
                  "imcModeProcessing": 0,
                  "itemFractionalAmount": "4/5"
              }}],
        "payments": [ {
                    "type": "cash",
                    "sum": 2000.00 }],
        "taxes": [],
        "total":  224.00,
        "clientInfo" : {
            "emailOrPhone": "address@mail.ru"
        },
        "companyInfo" : {
            "email": "test@ofd.ru"
        },
        "salesNotice" : {
            "timeZone": 2
        }
    })";
    doTest(req);
}

void testGetDeviceStatus()
{
    const char req[] = R"({"password":30,"type":"getDeviceStatus"})";
    doTest(req);
}

void testGetFNStatus()
{
    const char req[] = R"({"password":30,"type":"getFnStatus"})";
    doTest(req);
}

void testChashIn()
{
    const char req[] = R"({
        "type":"cashIn",
        "password":30,
        "cashSum":1150.0,
        "operator":{
            "name":"Иванов",
            "vatin":"123654789507"}})";
    doTest(req);
}

void testChashOut()
{
    const char req[] = R"({
        "type":"cashOut",
        "password":30,
        "cashSum":150.25,
        "operator":{
            "name":"Иванов",
            "vatin":"123654789507"}})";
    doTest(req);
}

void testContinuePrint()
{
    const char req[] = R"({"type":"continuePrint", "password":30})";
    doTest(req);
}

void testValidateMarks()
{
    const char req[] = R"({
        "params":[
            {
                "imc":"MDE0NDk0NTUwNDM1MzA2ODIxUVhZWFNBTEdMTVlRUR05MUVFMDYdOTJZV0NYYm1LNlNOOHZ2d294WkZrN1dBWThXb0pOTUdHcjZDZ3RpdWphMDRjPQ",
                "imcModeProcessing":0,
                "imcType":"auto",
                "itemEstimatedStatus":"itemDryForSale",
                "itemFractionalAmount":"4/5",
                "itemQuantity":1,
                "itemUnits":"piece"
            }],
            "timeout":60000,
            "type":"validateMarks"
        })";
    doTest(req);
}

void testNonFiscal()
{
    const char req[] = R"({
        "items":[
            {
                "alignment":"center",
                "text":"ИНН: 7725760410 КПП: 772501001",
                "type":"text"},
            {
                "alignment":"center",
                "text":"КАССА: 00105700000011 СМЕНА:1",
                "type":"text"},
            {
                "alignment":"center",
                "text":"ЧЕК: 1 ДАТА: 20.06.2017 14:12",
                "type":"text"},
            {
                "barcode":"https://check.egais.ru?id=cf1b1096-3cbc-11e7-b3c1-9b018b2ba3f7",
                "barcodeType":"QR",
                "scale":7,
                "type":"barcode"},
            {
                "firstLine":1,
                "lastLine":20,
                "type":"pictureFromMemory"},
            {
                "alignment":"center",
                "text":"https://check.egais.ru?id=cf1b1096-3cbc-11e7-b3c1-9b018b2ba3f7",
                "type":"text"},
            {
                "alignment":"center",
                "pixels":"////////////////////////////////////////////////////////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA//////////////////////////////////////////////////////////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP///////////////////////////////////////////////////////w==",
                "scale":1,
                "type":"pixels",
                "width":20},
            {
                "alignment":"center",
                "text":"10 58 1c 85 ab 45 29 fa 34 a7 34 10 58 1c 85 ab 45 29 fa 34 a7 34 10 58 1c 85 ab 45 29 fa 34 a7 34 10 58 1c 85 ab 45 29 fa 34 a7 34 34 a7 34 10 58",
                "type":"text"}],
        "password":30,
        "type":"nonFiscal"
        })";
    doTest(req);
}

void testLoadImage()
{
    const char req[] = R"({
        "line":0,
        "pixels":"////////////////////////////////////////////////////////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA//////////////////////////////////////////////////////////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAD/////AAAAAAAA//8AAAAAAAAAAP///////////////////////////////////////////////////////w==",
        "type":"loadImage",
        "width":20
    })";
    doTest(req);
}

void testSellCorrectionFfd12()
{
    const char req[] = R"({
        "type":"sellCorrection",
        "password":30,
        "clientInfo": {
            "emailOrPhone":"address@mail.ru"},
        "companyInfo":{
            "email":"test@ofd.ru"},
        "correctionBaseDate":"2025.10.29",
        "correctionBaseNumber":"1175",
        "correctionType":"self",
        "items":[{
                 "amount":299.95,
                 "imcParams":{
                    "imc":"MDE0NDk0NTUwNDM1MzA2ODIxUVhZWFNBTEdMTVlRUR05MUVFMDYdOTJZV0NYYm1LNlNOOHZ2d294WkZrN1dBWThXb0pOTUdHcjZDZ3RpdWphMDRjPQ",
                    "imcModeProcessing":0,
                    "imcType":"auto",
                    "itemEstimatedStatus":"itemDryForSale",
                    "itemFractionalAmount":"4/5",
                    "itemQuantity":1,
                    "itemUnits":"piece"},
                 "infoDiscountAmount":0.0,
                 "measurementUnit":"piece",
                 "name":"*3282705 Товар",
                 "paymentMethod":"fullPayment",
                 "paymentObject":"commodityWithMarking",
                 "price":299.95,
                 "quantity":1.0,
                 "tax":{
                    "sum":0.0,"type":"vat20"},
                 "type":"position"}],
        "operator":{
            "name":"Иванов",
            "vatin":""},
        "payments":[{
            "sum":2000.0,
            "type":"cash"}],
        "salesNotice":{
            "timeZone":2},
        "taxes":[],
        "total":"224.0"
    })";
    doTest(req);
}

void testBeginValidateMark()
{
    const char req[] = R"({
        "type":"beginMarkingCodeValidation",
        "password":30,
        "params":{
            "imc":"MDEwMDQ2MjA5ODQ5MDAwMDIxanhrZCVLaB04MDA1MDE3NTAwHTkzZEdWeg==",
            "imcModeProcessing":0,
            "imcType":"auto",
            "itemEstimatedStatus":"itemDryForSale",
            "itemQuantity":1.521,
            "itemUnits":"kilogram",
            "notSendToServer":false
        }})";
    doTest(req);
}

void testAcceptMarkingCode()
{
    const char req[] = R"({"type":"acceptMarkingCode", "password":30})";
    doTest(req);
}

void testDeclineMarkingCode()
{
    const char req[] = R"({"type":"declineMarkingCode", "password":30})";
    doTest(req);
}

int main(int argc, char* argv[])
{
    // поиск устройства длительная операция
    // пользуйтесь ей только при первоначальной настройке устройства
    // сохраните полученный URI устройства в настройках приложения

    //testConfigureDiscover();

    // вызывайте функцию configure c заданным URI каждый раз при запуске
    // приложения перед началом работы с драйвером
#ifdef __APPLE__
    testConfigureMac();
#endif
#ifdef _WIN32
    testConfigureWin();
#endif

    // Примеры вызовов функций драйвера:

    // testOpenShift();
    // testLoadImage();
    // testSellFfd12();
    // testSellCorrectionFfd12();
    // testGetDeviceStatus();
    // testGetFNStatus();
    // testChashIn();
    // testChashOut();
    // testReportX();
    // testValidateMarks();
    // testBeginValidateMark();
    // testAcceptMarkingCode();
    // testDeclineMarkingCode();
    //  testNonFiscal();
     testCloseShift();
}