/*! @file

    @id $Id$
*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#ifndef SUISSE_ID_DEMO_HXX
#define SUISSE_ID_DEMO_HXX

#include <suisseid.hxx>
#include <iostream>
#include <cassert>

// implements a status cycle for text user interface
class TextualCycle: public suisseid::StatusCycle {

  public:

    // just pass the card to parent
    TextualCycle(std::shared_ptr<suisseid::Card> card):
        StatusCycle(card) {
    }

  protected:

    // callback: ask user for transport pin 
    virtual PinPukChange pinChangeTransportPin() {
      PinPukChange pinpuk;
      std::cout<<"Enter Transport PIN: ";
      std::cin>>pinpuk.oldpin;
      std::cout<<"Enter New PIN: ";
      std::cin>>pinpuk.newpin;
      return pinpuk;
    }

    // callback: ask user for puk
    virtual PinPukChange pinChangePuk() {
      PinPukChange pinpuk;
      std::cout<<"Enter PUK to unlock PKCS#15 PIN: ";
      std::cin>>pinpuk.oldpin;
      std::cout<<"Enter New PKCS#15 PIN: ";
      std::cin>>pinpuk.newpin;
      return pinpuk;
    }
    
    // callback: tell user that transport pin is locked
    virtual void transportPinLocked() {
      std::cout<<"Transport PIN is Locked!"<<std::endl;
    }

    // callback: tell user that pkcs15 pin is locked
    virtual void pkcs15PinLocked() {
      std::cout<<"PKCS#15 PIN is Locked!"<<std::endl;
    }

    // callback: tell user that digital signature pin is locked
    virtual void sigGPinLocked() {
      std::cout<<"SigG PIN is Locked!"<<std::endl;
    }

    // callback: tell user that puk is locked
    virtual void pukLocked() {
      std::cout<<"PUK is Locked!"<<std::endl;
    }

    // callback: tell user that certificates will expire soon
    virtual void certsExpireSoon() {
      std::cout<<"Certificates Expire Soon!"<<std::endl;
    }

    // callback: tell user that certificates have expired
    virtual void certsExpired() {
      std::cout<<"Certificates Expired!"<<std::endl;
    }

    // callback: tell user that certificates have been revoked
    virtual void certsRevoked() {
      std::cout<<"Certificates Revoked!"<<std::endl;
    }

  public:

    // install certificates on the card
    virtual bool installCerts(bool force = true) {
      std::cout<<"Installing Certificates ..."<<std::endl;
      std::string pin;
      std::cout<<"Enter PIN (x to abort): ";
      std::cin>>pin;
      if (pin=="x") {
        std::cout<<std::endl<<"User aborted"<<std::endl;
        return false; // user aborts
      }
      cryptoki::Session session(card()->slot());
      try {
        // log into the card using the user's pin
        session.login(pin);
      } catch (const cryptoki::wrong_pin& x) {
        std::cout<<"**** Wrong PIN!"<<std::endl;
        std::cout<<x.what()<<std::endl;
        return false;
      }
      // now store certificates on the card
      std::cout<<"**** Not implemented"<<std::endl;
      return true;
    }

};

#endif
