#include "auth_digest.hpp"
#include "user_info.hpp"
 
#include "sql/queries.hpp"
 
#include <algorithm>
#include <optional>
#include <string_view>
 
 
namespace samples::digest_auth {
 
using TimePoint = std::chrono::time_point<std::chrono::system_clock>;
 
class AuthChecker final
 public:
  using AuthDigestSettings =
 
  AuthChecker(const AuthDigestSettings& digest_settings, std::string realm,
              const ::components::ComponentContext& context,
              const SecdistConfig& secdist_config)
            digest_settings, std::move(realm), secdist_config),
        nonce_ttl_(digest_settings.nonce_ttl) {}
 
  std::optional<UserData> FetchUserData(
      const std::string& username) const override;
 
  void SetUserData(const std::string& username, const std::string& nonce,
                   std::int64_t nonce_count,
                   TimePoint nonce_creation_time) const override;
 
  void PushUnnamedNonce(std::string nonce) const override;
 
  std::optional<TimePoint> GetUnnamedNonceCreationTime(
      const std::string& nonce) const override;
 
 private:
  const std::chrono::milliseconds nonce_ttl_;
};
 
std::optional<UserData> AuthChecker::FetchUserData(
    const std::string& username) const {
                           uservice_dynconf::sql::kSelectUser, username);
 
  if (res.
IsEmpty()) 
return std::nullopt;
 
 
  auto user_db_info = res.
AsSingleRow<UserDbInfo>(storages::postgres::kRowTag);
 
  return UserData{HA1{user_db_info.ha1}, user_db_info.nonce,
                  user_db_info.timestamp.GetUnderlying(),
                  user_db_info.nonce_count};
}
 
void AuthChecker::SetUserData(const std::string& username,
                              const std::string& nonce,
                              std::int64_t nonce_count,
                              TimePoint nonce_creation_time) const {
                       uservice_dynconf::sql::kUpdateUser, nonce,
                       nonce_count, username);
}
 
void AuthChecker::PushUnnamedNonce(std::string nonce) const {
  auto res = pg_cluster_->Execute(
      uservice_dynconf::sql::kInsertUnnamedNonce,
}
 
std::optional<TimePoint> AuthChecker::GetUnnamedNonceCreationTime(
    const std::string& nonce) const {
  auto res =
                           uservice_dynconf::sql::kSelectUnnamedNonce, nonce);
 
  if (res.IsEmpty()) return std::nullopt;
 
}
 
server::handlers::auth::AuthCheckerBasePtr CheckerFactory::operator()(
    const ::components::ComponentContext& context,
  const auto& digest_auth_settings =
      context
          .FindComponent<
          .GetSettings();
 
  return std::make_shared<AuthChecker>(
      digest_auth_settings, auth_config["realm"].As<std::string>({}), context,
}
 
server::handlers::auth::AuthCheckerBasePtr CheckerProxyFactory::operator()(
    const ::components::ComponentContext& context,
  const auto& digest_auth_settings =
      context
          .FindComponent<
              "auth-digest-checker-settings-proxy")
          .GetSettings();
 
  return std::make_shared<AuthChecker>(
      digest_auth_settings, auth_config["realm"].As<std::string>({}), context,
}
 
}