#include <eedb/auth/Services.hpp>

#include <Wt/Auth/PasswordService>
#include <Wt/Auth/PasswordStrengthValidator>
#include <Wt/Auth/PasswordVerifier>

#include <Wt/Auth/AuthService>
#include <Wt/Auth/AuthWidget>
#include <Wt/Auth/Dbo/AuthInfo>
#include <Wt/Auth/Dbo/UserDatabase>
#include <Wt/Auth/FacebookService>
#include <Wt/Auth/GoogleService>
#include <Wt/Auth/HashFunction>
#include <Wt/Auth/Login>

namespace {

class MyOAuth : public std::vector< const Wt::Auth::OAuthService * > {
  public:
    ~MyOAuth() {
        for(unsigned i = 0; i < size(); ++i)
            delete(*this)[i];
    }
};

Wt::Auth::AuthService myAuthService;
Wt::Auth::PasswordService myPasswordService(myAuthService);
MyOAuth myOAuthServices;
}

namespace eedb::auth {
Wt::Auth::AuthService * Services::authService() {
    return &myAuthService;
}

Wt::Auth::AbstractPasswordService * Services::passwordService() {
    return &myPasswordService;
}

std::vector< const Wt::Auth::OAuthService * > Services::oAuthServices() {
    return myOAuthServices;
}

void Services::configureAuth() {
    myAuthService.setAuthTokensEnabled(true, "logincookie");
    myAuthService.setEmailVerificationEnabled(true);
    myAuthService.setEmailVerificationRequired(true);

    Wt::Auth::PasswordVerifier * verifier = new Wt::Auth::PasswordVerifier();
    verifier->addHashFunction(new Wt::Auth::BCryptHashFunction(7));
    myPasswordService.setVerifier(verifier);
    myPasswordService.setAttemptThrottlingEnabled(true);
    myPasswordService.setStrengthValidator(new Wt::Auth::PasswordStrengthValidator());

    if(Wt::Auth::GoogleService::configured())
        myOAuthServices.push_back(new Wt::Auth::GoogleService(myAuthService));

    if(Wt::Auth::FacebookService::configured())
        myOAuthServices.push_back(new Wt::Auth::FacebookService(myAuthService));

    for(unsigned i = 0; i < myOAuthServices.size(); ++i)
        myOAuthServices[i]->generateRedirectEndpoint();
}
};
