// ---------------------------------------------------------------------------
// - Pem.hxx                                                                 -
// - afnix:tls service - pem codec private definitions                       -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2020 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef  AFNIX_PEM_HXX
#define  AFNIX_PEM_HXX

#ifndef  AFNIX_ITEM_HPP
#include "Item.hpp"
#endif

namespace afnix {
  
  // the object eval quarks
  static const long QUARK_PEM      = String::intern ("Pem");
  static const long QUARK_PEMCNONE = String::intern ("NONE");
  static const long QUARK_PEMCKEYP = String::intern ("PRIVATE-KEY");
  static const long QUARK_PEMCKEYK = String::intern ("PUBLIC-KEY");
  static const long QUARK_PEMCRSAP = String::intern ("RSA-PRIVATE-KEY");
  static const long QUARK_PEMCRSAK = String::intern ("RSA-PUBLIC-KEY");
  static const long QUARK_PEMCDSAP = String::intern ("DSA-PRIVATE-KEY");
  static const long QUARK_PEMCDSAK = String::intern ("DSA-PUBLIC-KEY");
  static const long QUARK_PEMCDSAM = String::intern ("DSA-PARAMETERS");
  static const long QUARK_PEMCDHEP = String::intern ("DH-PRIVATE-KEY");
  static const long QUARK_PEMCDHEK = String::intern ("DH-PUBLIC-KEY");
  static const long QUARK_PEMCDHEM = String::intern ("DH-PARAMETERS");
  static const long QUARK_PEMCCERT = String::intern ("CERTIFICATE");

  // map an item to a pem type
  static inline Pem::t_pemc item_to_pemc (const Item& item) {
    // check for a key item
    if (item.gettid () != QUARK_PEM)
      throw Exception ("item-error", "item is not a pem item");
    // map the item to the enumeration
    long quark = item.getquark ();
    if (quark == QUARK_PEMCNONE) return Pem::PEMC_NONE;
    if (quark == QUARK_PEMCKEYP) return Pem::PEMC_KEYP;
    if (quark == QUARK_PEMCKEYK) return Pem::PEMC_KEYK;
    if (quark == QUARK_PEMCRSAP) return Pem::PEMC_RSAP;
    if (quark == QUARK_PEMCRSAK) return Pem::PEMC_RSAK;
    if (quark == QUARK_PEMCDSAP) return Pem::PEMC_DSAP;
    if (quark == QUARK_PEMCDSAK) return Pem::PEMC_DSAK;
    if (quark == QUARK_PEMCDSAM) return Pem::PEMC_DSAM;
    if (quark == QUARK_PEMCDHEP) return Pem::PEMC_DHEP;
    if (quark == QUARK_PEMCDHEK) return Pem::PEMC_DHEK;
    if (quark == QUARK_PEMCDHEM) return Pem::PEMC_DHEM;
    if (quark == QUARK_PEMCCERT) return Pem::PEMC_CERT;
    throw Exception ("item-error", "cannot map item to pem type");
  }

  // map a pem type to an item
  static inline Item* pemc_to_item (const Pem::t_pemc pemc) {
    switch (pemc) {
    case Pem::PEMC_NONE:
      return new Item (QUARK_PEM, QUARK_PEMCNONE);
      break;
    case Pem::PEMC_KEYP:
      return new Item (QUARK_PEM, QUARK_PEMCKEYP);
      break;
    case Pem::PEMC_KEYK:
      return new Item (QUARK_PEM, QUARK_PEMCKEYK);
      break;
    case Pem::PEMC_RSAP:
      return new Item (QUARK_PEM, QUARK_PEMCRSAP);
      break;
    case Pem::PEMC_RSAK:
      return new Item (QUARK_PEM, QUARK_PEMCRSAK);
      break;
    case Pem::PEMC_DSAP:
      return new Item (QUARK_PEM, QUARK_PEMCDSAP);
      break;
    case Pem::PEMC_DSAK:
      return new Item (QUARK_PEM, QUARK_PEMCDSAK);
      break;
    case Pem::PEMC_DSAM:
      return new Item (QUARK_PEM, QUARK_PEMCDSAM);
      break;
    case Pem::PEMC_DHEP:
      return new Item (QUARK_PEM, QUARK_PEMCDHEP);
      break;
    case Pem::PEMC_DHEK:
      return new Item (QUARK_PEM, QUARK_PEMCDHEK);
      break;
    case Pem::PEMC_DHEM:
      return new Item (QUARK_PEM, QUARK_PEMCDHEM);
      break;
    case Pem::PEMC_CERT:
      return new Item (QUARK_PEM, QUARK_PEMCCERT);
      break;
    }
    return nullptr;
  }
}

#endif
