#pragma once
#include <stdint.h>
#include <string>
#include <vector>

// pin entry result codes
#define PIN_ENTERED                          0
#define PIN_BYPASSED                         1
#define PIN_PINPAD_NOT_PRESENT_OR_MALUNCTION 2

#define KEY_BLOCK_FORMAT_PLAINTEXT 0 // в открытом виде (для мастер ключа)
#define KEY_BLOCK_FORMAT_TR31      1 // TR-31
#define KEY_BLOCK_FORMAT_MK        2 // ключ зашифрован мастер ключом (ECB)
#define KEY_BLOCK_FORMAT_MK_CBC    3 // ключ зашифрован мастер ключом (CBC)

#define KEY_ALG_TDEA2K 0 // 3DES 16 byte key
#define KEY_ALG_TDEA3K 1 // 3DES 24 byte key
#define KEY_ALG_AES256 2 // AES 32 byte keys
#define KEY_ALG_AES192 3 // AES 24 byte keys
#define KEY_ALG_AES128 4 // AES 16 byte keys

#define MODE_ECB 0
#define MODE_CBC 1

#define MAC_ALG_X919             0
#define MAC_ALG_RETAIL_3DES_NONE 1

#define KEY_USAGE_DATA 0 // ключ для шифрования произвольных данных
#define KEY_USAGE_KEK  1 // ключ для шифрования ключей
#define KEY_USAGE_PEK  3 // ключ для шифрования ПИН-кода
#define KEY_USAGE_MAC  4 // ключ для вычисления MAC

#define RESULT_INVALID_KEY_USAGE       -31
#define RESULT_KEY_DOES_NOT_EXIST      -32
#define RESULT_INVALID_ARGUMENT        -33
#define RESULT_FEATURE_IS_NOT_SUPORTED -34
#define RESULT_DUPICATED_KEY_VALUE     -35
#define RESULT_WEAK_MASTER_KEY         -36
#define RESULT_FAILED                  -37

#define STATUS_SUCCESS            0
#define STATUS_TIMEOUT            -1
#define STATUS_INVALID_PARAMETER  -4
#define STATUS_WRITE_ERROR        -3
#define STATUS_READ_ERROR         -5
#define STATUS_MEMORY_ERROR       -6
#define STATUS_FORMAT_ERROR       -7
#define STATUS_FAILED             -8
#define STATUS_NOT_PRESENT        -9
#define STATUS_PROTOCOL_ERROR     -10
#define STATUS_TRANSMISSION_ERROR -11
#define STATUS_STOP               -12
#define STATUS_COLLISION_ERROR    -13
#define STATUS_NOT_IMPLEMENTED    -14

int secserv_helper_init (uint32_t pinblock_format, uint32_t pin_key_idx, const std::string& lang);
int secserv_helper_deinit ();
// PCI compat API
int secserv_get_random_bytes (uint8_t* buf, size_t size);
int secserv_import_key (int key, int alg, int usage, int master, int format, std::vector<uint8_t> kb);
int secserv_generate_key (int key, int alg, int usage);
int secserv_get_key_info (int key, int* alg, int* usage, int* block_size, std::vector<uint8_t>* kcv);
int secserv_compute_mac (int key, int alg, const std::vector<uint8_t>& data, std::vector<uint8_t>* mac);
int secserv_encrypt (int key, int mode, const std::vector<uint8_t>& din, const std::vector<uint8_t>* iv, std::vector<uint8_t>* dout);
int secserv_decrypt (int key, int mode, const std::vector<uint8_t>& din, const std::vector<uint8_t>* iv, std::vector<uint8_t>* dout);
int secserv_get_crk (std::vector<uint8_t>* cert);

// L2 compat api
int secserv_getOnlinePinblock (const std::vector<uint8_t>& pan, const std::string& lpref, std::vector<uint8_t>& pb, const std::string& prompt = "");
int secserv_verifyOfflinePinEncrypted (int ptc, std::string lpref, const std::vector<uint8_t>& mod, const std::vector<uint8_t>& exp, const std::vector<uint8_t>& challenge, std::vector<uint8_t>& sw12, const std::string& prompt = "");
int secserv_verifyOfflinePinPlain (int ptc, std::string lpref, std::vector<uint8_t>& sw12, const std::string& prompt = "");

// L3 compat api
int secserv_select_lang (std::string* lang, const std::string& lpref, uint32_t timeout);
int secserv_select_aid (uint32_t* aid, const std::vector<std::string>& names, uint32_t timeout);
