#ifndef PLC_LICENCE21_H
#define PLC_LICENCE21_H

#include <stdint.h>
#include <iostream>
#include <unordered_map>
#include <vector>
#include "utils.h"
#include "licenceCommon.h"
#include "SDCard.h"

using namespace std;

class LicenceELC21
{
  const string cid_cdsPath = ""; //"c:\\_projects\\LicenceGenerator\\output\\"; ///sys/block/mmcblk0/device/
  const string licenceFilePath = ""; //"c:\\_projects\\LicenceGenerator\\output\\";
  
  enum class Error21
  {
    SDCardReadError = 50,
    LicenceReadError = 51,
    LicenceSizeMismatch = 52,
    LicenceSizeCardMismatch = 53,
    LicenceMismatch = 54,
    ItemsCountMismatch = 61
  };

  unordered_map<Error21, string> map21Errors = {
      {Error21::SDCardReadError, "Nepodařilo se načíst SD kartu."},
      {Error21::ItemsCountMismatch, "Nesouhlasí počet položek licence."},
      {Error21::LicenceSizeMismatch, "Nesouhlasí velikost souboru licence."},
      {Error21::LicenceSizeCardMismatch, "Nesouhlasí velikost SD karty."},
      {Error21::LicenceMismatch, "Nesouhlasí licence."},
      {Error21::ItemsCountMismatch, "Nesouhlasí počet položek licence."},
  };
  

  struct LicenceId
  {
    char licIdent[5] = { 'E', 'L', 'C', '0','_'};
  };

  //struct __attribute__((__packed__)) LicencePublicHeader

  struct LicenceIdentDataHeader
  {
    BYTE licenceType = 0; //EOSEOV, DRT ...
    BYTE licenceTypeVersion = 1; //verze licence, urcuje nuance sifrování a pojmenování souborů
    BYTE licenceIndex = 0; //puvodní post fix, identifikátor pro více licencí
    BYTE compatibilityVersion = 1; //udava verzi komplet PrivateContent
    BYTE licItemCount = 0; //počet licenčních bodů
    WORD publicHeaderLength = 0; //délka veřejné hlavičy
    WORD cardSize = 0; //velikost SD karty
    DWORD serialNumber = 0;//seriove cislo karty
  };

  /// 
  struct licDataItem
  {
     WORD protoId = 0;  // id protokolu pro ktery je licence
     WORD licCount = 0; // pocet datovych bodu licence
     char dummy[64] = {};
  };

  struct PublicHeader
  {
    string version = "";
    string projectDescription = "";
    string date = "";
    string licenceType = "";
    int crc = 0;
  };

  struct PrivateContent //privátní šifrovaná část
  {
    LicenceIdentDataHeader licenceIdentHeader;
    vector<licDataItem> dataItems;
    WORD crc = 0;
  };

  struct LicenceBody
  {
    LicenceId licId;
    LicenceIdentDataHeader licenceIdentHeader;
    string publicHeader = ""; //JSON
    PrivateContent privateContent; 
  };

  private:
  int licItemCount = 0;
  LicenceBody licBody;
  LicenceIdentification lIdentification;
  LicData lData;
  SDCard sdCard;
  void getHeader();
  string getVersion(int middleVersion);
  void getLicenceItems();
  bool processInputConfiguration();
  vector<unsigned char> cryptPrivateContent(const std::vector<unsigned char>& content);
  vector<unsigned char> decryptPrivateContent(const std::vector<unsigned char>& content);
  void initVector(BYTE (&iVector)[], BYTE (&key)[]);
  string getLicenceName();


  public:
  
  ErrorMessage errorMessage;
  LicenceInfo21 licenceInfo;

  LicenceELC21();
  ~LicenceELC21();
  LicenceELC21(LicenceIdentification & licIdentification, LicData & icData);
  LicenceELC21(LicenceIdentification & licIdentification);
  LicenceELC21(LicData & icData);
  bool createLicence();
  bool readLicence(LicenceInfoGeneral * licences);
  int getDataPointsCount(int protocolId);
  bool getLicenceInfo(int protocolId, void * ptr);
  bool getLicenceItemInfo(int protocolId, void *returnItemStructure);


};

#endif
