/*!
 * \file      certificate_loader.hh
 * \brief     Header file for ITS certificates loader definition.
 * \author    ETSI STF525
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 * \remark Use xxd -p -c32 <file name> to make a hexdump or do the reverse (e.g. xxd -p -c32 CERT_IUT_A_RCA.vkey)
 */
#pragma once

#include <set>
#include <map>
#include <string>

#include <experimental/filesystem>

#include "security_db_record.hh"

/*!
 * \class certificates_loader
 * \brief This class provides mechanism  to load the certificates from the filesystem according the struecture defined in ETSI TS 103 099
 * \remark Singleton pattern
 */
class certificates_loader {
  
  std::string _certificateExt;
  
  std::string _privateKeyExt;

  std::string _publicKeysExt;

  std::string _publicCompKeysExt;

  std::string _privateEncKeyExt;

  std::string _publicEncKeysExt;

  std::string _hashedidDigestExt;

  std::string _issuerDigestExt;

  /*!
   * \brief The full folder path to load certificates
   */
  std::experimental::filesystem::path _full_path;

  /*!
   * \brief Set to true when certificates are successfully loaded from file system
   */
  bool _is_cache_initialized;
  
  /*!
   * \brief Directory filter (for local development purposes only
   */
  std::set<std::string> _directory_filter;

  /*!
   * \brief Unique static object reference of this class
   */
  static certificates_loader* instance;

  /*!
   * \brief Default private ctor
   */
  certificates_loader();
  /*!
   * \brief Default private dtor
   */
  ~certificates_loader() {
    if (instance != NULL) {
      delete instance;
      instance = NULL;
    }
  };
  
public: /*! \publicsection */

  /*!
   * \brief Public accessor to the single object reference
   */
  inline static certificates_loader& get_instance() {
    if (instance == NULL) instance = new certificates_loader();
    return *instance;
  };

  int build_path(const std::string& p_root_directory);

  int load_certificates(std::map<std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<std::vector<unsigned char>, std::string>& p_hashed_id8s);
  //int load_certificate(std::unique_ptr<security_db_record> >& p_certificate, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s);
  int save_certificate(const security_db_record& p_certificate);

private:
  int retrieve_certificates_list(std::set<std::experimental::filesystem::path>& p_files);

  int build_certificates_cache(std::set<std::experimental::filesystem::path>& p_files, std::map<std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<std::vector<unsigned char>, std::string>& p_hashed_id8s);
  
}; // End of class certificates_loader
