// ---------------------------------------------------------------------------
// - Predcsm.cpp                                                             -
// - afnix:csm service - predicates implementation                           -
// ---------------------------------------------------------------------------
// - 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-2019 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Cons.hpp"
#include "Visa.hpp"
#include "Domain.hpp"
#include "Notary.hpp"
#include "Tracker.hpp"
#include "Predcsm.hpp"
#include "Boolean.hpp"
#include "Delegate.hpp"
#include "Exception.hpp"
#include "LocalZone.hpp"
#include "RealmZone.hpp"
#include "UserSpace.hpp"
#include "SessionSet.hpp"

namespace afnix {

  // this procedure checks that we have one argument only and returns
  // the evaluated object
  static inline Object* get_obj (Runnable* robj, Nameset* nset, Cons* args,
                                 const String& pname) {
    Object* car = nullptr;
    if ((args == nullptr) || (args->length () != 1))
      throw Exception ("argument-error", "illegal arguments with predicate",
                       pname);
    car = args->getcar ();
    return (car == nullptr) ? nullptr : car->eval (robj,nset);
  }

  // partp: part object predicate

  Object* csm_partp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "part-p");
    bool result = (dynamic_cast <Part*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // blobp: blob object predicate

  Object* csm_blobp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "blob-p");
    bool result = (dynamic_cast <Blob*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // blocp: bloc object predicate

  Object* csm_blocp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "bloc-p");
    bool result = (dynamic_cast <Bloc*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // cblbp: carrier blob object predicate

  Object* csm_cblbp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "carrier-p");
    bool result = (dynamic_cast <Carrier*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // dblbp: delegate blob object predicate

  Object* csm_dblbp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "delegate-p");
    bool result = (dynamic_cast <Delegate*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // tckrp: tracker blob object predicate

  Object* csm_tckrp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "tracker-p");
    bool result = (dynamic_cast <Tracker*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // collp: collection object predicate

  Object* csm_collp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "collection-p");
    bool result = (dynamic_cast <Collection*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // domnp: domain object predicate

  Object* csm_domnp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "domain-p");
    bool result = (dynamic_cast <Domain*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // sessp: session object predicate
  
  Object* csm_sessp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "session-p");
    bool result = (dynamic_cast <Session*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // ssetp: session set object predicate
  
  Object* csm_ssetp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "session-set-p");
    bool result = (dynamic_cast <SessionSet*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // wzonp: workzone predicate

  Object* csm_wzonp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "workzone-p");
    bool result = (dynamic_cast <WorkZone*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // wspcp: workspace predicate

  Object* csm_wspcp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "workspace-p");
    bool result = (dynamic_cast <WorkSpace*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // lzonp: localzone predicate

  Object* csm_lzonp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "localzone-p");
    bool result = (dynamic_cast <LocalZone*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // lspcp: localspace predicate

  Object* csm_lspcp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "localspace-p");
    bool result = (dynamic_cast <LocalSpace*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // uspcp: userspace predicate

  Object* csm_uspcp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "userspace-p");
    bool result = (dynamic_cast <UserSpace*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // relmp: realm predicate

  Object* csm_relmp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "realm-p");
    bool result = (dynamic_cast <Realm*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // rzonp: realm zone predicate

  Object* csm_rzonp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "realzonem-p");
    bool result = (dynamic_cast <RealmZone*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // idtyp: identity predicate

  Object* csm_idtyp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "identity-p");
    bool result = (dynamic_cast <Identity*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // authp: authority predicate

  Object* csm_authp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "authority-p");
    bool result = (dynamic_cast <Authority*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // pcplp: principal predicate

  Object* csm_pcplp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "principal-p");
    bool result = (dynamic_cast <Principal*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // xactp: act predicate

  Object* csm_xactp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "act-p");
    bool result = (dynamic_cast <Act*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // visap: visa predicate

  Object* csm_visap  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "visa-p");
    bool result = (dynamic_cast <Visa*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // credp: credential predicate

  Object* csm_credp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "credential-p");
    bool result = (dynamic_cast <Credential*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
  
  // ntryp: notary predicate

  Object* csm_ntryp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "notary-p");
    bool result = (dynamic_cast <Notary*> (obj) == nullptr) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
}
