/*
   This file is part of Challenger
   Copyright (C) 2023 Taler Systems SA

   Challenger is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 3, or (at your option) any later version.

   Challenger 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.  See the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along with
   Challenger; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
/**
 * @file challengerdb/pg_validation_get_pkce.c
 * @brief Implementation of the validation_get_pkce function for Postgres
 * @author Bohdan Potuzhnyi
 * @author Vlada Svirsh
 */
#include "platform.h"
#include <taler/taler_error_codes.h>
#include <taler/taler_dbevents.h>
#include <taler/taler_pq_lib.h>
#include "pg_validation_get_pkce.h"
#include "pg_helper.h"

enum GNUNET_DB_QueryStatus
CH_PG_validation_get_pkce (void *cls,
                      const struct CHALLENGER_ValidationNonceP *nonce,
                      char **client_secret,
                      json_t **address,
                      char **client_scope,
                      char **client_state,
                      char **client_redirect_uri,
                      char **code_challenge,
                      uint32_t *code_challenge_method)
{
  struct PostgresClosure *pg = cls;
  struct GNUNET_PQ_QueryParam params[] = {
    GNUNET_PQ_query_param_auto_from_type (nonce),
    GNUNET_PQ_query_param_end
  };
  struct GNUNET_PQ_ResultSpec rs[] = {
    GNUNET_PQ_result_spec_string ("client_secret",
                                  client_secret),
    GNUNET_PQ_result_spec_allow_null (
      TALER_PQ_result_spec_json ("address",
                                 address),
      NULL),
    GNUNET_PQ_result_spec_allow_null (
      GNUNET_PQ_result_spec_string ("client_scope",
                                    client_scope),
      NULL),
    GNUNET_PQ_result_spec_allow_null (
      GNUNET_PQ_result_spec_string ("client_state",
                                    client_state),
      NULL),
    GNUNET_PQ_result_spec_string ("redirect_uri",
                                  client_redirect_uri),
    GNUNET_PQ_result_spec_allow_null (
      GNUNET_PQ_result_spec_string ("code_challenge",
                                    code_challenge),
      NULL),
    GNUNET_PQ_result_spec_allow_null (
      GNUNET_PQ_result_spec_uint32 ("code_challenge_method",
                                    code_challenge_method),
      NULL),
    GNUNET_PQ_result_spec_end
  };

  *client_scope = NULL;
  *client_state = NULL;
  *address = NULL;
  PREPARE (pg,
           "validation_get_pkce",
           "SELECT "
           "  client_secret"
           " ,address"
           " ,client_scope"
           " ,client_state"
           " ,COALESCE(client_redirect_uri,uri) AS redirect_uri"
           " ,code_challenge"
           " ,code_challenge_method"
           " FROM validations"
           " JOIN clients "
           "  USING (client_serial_id)"
           " WHERE nonce=$1");
  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                   "validation_get_pkce",
                                                   params,
                                                   rs);
}
