#include "licReaderELC1.h"
#ifndef EZ_APPLICATION_LICENCE_DISABLE

namespace Reader
{
  Licence1::Licence1() {}

  Licence1::~Licence1() {}

  Licence1::Licence1(LicenceIdentification &licIdentification) : LicenceELC1(licIdentification)
  {
  }

  /// @brief načte seznam licenčních bodů do obecné struktury
  /// @param licences 
  /// @return 
  bool Licence1::readLicence(LicenceInfoGeneral *licences)
  {
  sdCard = SDCard(this->cid_cdsPath);
  if (sdCard.isLoaded == false) throw LicenceException((int)GeneralError::SDCardReadError, "Chyba při čtení SD karty, cesta: " + cid_cdsPath);
  
  for (unsigned int i = 0; i < CID_LENGTH;i++) this->cid[i] = sdCard.cid[i];
  for (unsigned int i = 0; i < CSD_LENGTH;i++) this->csd[i] = sdCard.csd[i];
  
  if (getSDData() == false) throw LicenceException((int)GeneralError::SDCardReadError, "Chyba při čtení SD karty, cesta: " + cid_cdsPath);

  string licFileName = getLicenceName(0);
  string licFilePath = this->licenceFilePath + licFileName;

  char licFileNameToRead[licFilePath.length()+1] = {};
  getCharsFromString(licFilePath, licFileNameToRead, licFilePath.length());

  FILE *licenceFile;
  char ch;

  licenceFile = fopen(licFileNameToRead, "rb"); 

  if (licenceFile == nullptr) throw LicenceException((int)GeneralError::LicenceReadError, "LicenceReadError: " + licFilePath);

  fseek(licenceFile, 0, SEEK_END);     
  const int size = ftell(licenceFile); 
  fseek(licenceFile, 0, SEEK_SET);

  if (size <= 0) throw LicenceException((int)GeneralError::LicenceSizeMismatch, "LicenceSizeMismatch: " + licFilePath);

  int count = 0;

  unsigned char licenceContent[size];

  for (int i = 0; i < size; i++)
  {
    ch = fgetc(licenceFile);
    licenceContent[i] = ch;
    count++;
  }

  fclose(licenceFile);
  
  LicenceDataMainELC licenceHeader{};
  LicenceData licEncryptedData{};

  memcpy(&licenceHeader, licenceContent, sizeof(LicenceDataMainELC));

  const int sizeOfEncryptedData = size - sizeof(LicenceDataMainELC);
  unsigned char encryptedData[sizeOfEncryptedData] = {};
  for (int i = 0; i < sizeOfEncryptedData; i++)
    encryptedData[i] = licenceContent[i + sizeof(LicenceDataMainELC)];

  BYTE prefixType = (int)licenceContent[3] - 0x30;
  if (prefixType == PrefixType::ELC1)
  {
    if (licenceHeader.licHeader.sizeData > 0)
    {
      if (licenceHeader.licHeader.licSubType == cEzLic_p78ou3_SubType_10_10)
      {
        initCrypto();

        unsigned char decrypted[2000] = {};
        int decrypted_len = decrypt(encryptedData, sizeof(encryptedData), cryptData.aesKey, cryptData.aesInitVector, decrypted);

        if (sizeof(licEncryptedData) != decrypted_len)
        {
          throw LicenceException((int)GeneralError::LicenceSizeMismatch, "License size mismatch ");
        }
        else
        {
          memcpy(&licEncryptedData, decrypted, sizeof(licEncryptedData));

          if (licEncryptedData.id.version == cEzLic_p78ou3_HeaderType_10 && licEncryptedData.header.licVersion == cEzLic_p78ou3_HeaderType_10)
          {
            if (licEncryptedData.header.licType == cEzLic_p78ou3_IDType_EOVOSV)
            {
              if (licEncryptedData.header.licCount > 0)
              {
                for (int i = 0; i < licMaxCount; i++)
                {
                  licences->licences.insert(pair<int, int>(licEncryptedData.items[i].protoId, licEncryptedData.items[i].licCount));
                }
              }
              else
              {
                throw LicenceException((int)GeneralError::ItemsCountMismatch, "ItemsCountMismatch");
              }
            }
          }
          else
          {
            throw LicenceException((int)GeneralError::LicenceMismatch, "Licence mismatch");
          }
        }
      }
    }
    else
    {
      throw LicenceException((int)GeneralError::LicenceMismatch, "Licence mismatch");
    }
  }
  else
  {
    throw LicenceException((int)GeneralError::LicenceReadError, "Licence error");
  }

  return true;
  }
}

#endif