/*
   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 src/challengerdb/delete_client.c
 * @brief Implementation of the delete_client function for Postgres
 * @author Christian Grothoff
 */
#include "platform.h"
#include <taler/taler_error_codes.h>
#include <taler/taler_dbevents.h>
#include <taler/taler_pq_lib.h>
#include "delete_client.h"
#include "pg_helper.h"


enum GNUNET_DB_QueryStatus
CHALLENGERDB_delete_client (struct CHALLENGERDB_PostgresContext *ctx,
                            const char *client_redirect_uri,
                            uint64_t *validations_deleted)
{
  struct GNUNET_PQ_QueryParam params[] = {
    GNUNET_PQ_query_param_string (client_redirect_uri),
    GNUNET_PQ_query_param_end
  };
  bool deleted;
  struct GNUNET_PQ_ResultSpec rs[] = {
    GNUNET_PQ_result_spec_uint64 ("validations_deleted",
                                  validations_deleted),
    GNUNET_PQ_result_spec_bool ("deleted",
                                &deleted),
    GNUNET_PQ_result_spec_end
  };
  enum GNUNET_DB_QueryStatus qs;

  *validations_deleted = 0;
  /* validations_client_serial_id_fkey is ON DELETE CASCADE, so deleting a
     client silently discards all of its validations -- KYC processes that
     are in flight right now.  Delete them here explicitly instead, so that
     we can tell the operator how many were lost.  Note that access tokens
     already issued are *not* affected: 'tokens' has no client reference at
     all and thus cannot be revoked per client. */
  PREPARE (ctx,
           "delete_client",
           "WITH victim AS ("
           "  SELECT client_serial_id"
           "    FROM clients"
           "   WHERE uri=$1"
           "), dv AS ("
           "  DELETE FROM validations"
           "   WHERE client_serial_id IN"
           "     (SELECT client_serial_id FROM victim)"
           "  RETURNING validation_serial_id"
           "), dc AS ("
           "  DELETE FROM clients"
           "   WHERE uri=$1"
           "  RETURNING client_serial_id"
           ") SELECT"
           "   (SELECT COUNT(*) FROM dv) AS validations_deleted"
           "  ,EXISTS (SELECT 1 FROM dc) AS deleted;");
  qs = GNUNET_PQ_eval_prepared_singleton_select (ctx->conn,
                                                 "delete_client",
                                                 params,
                                                 rs);
  if (0 >= qs)
    return qs;
  return deleted
         ? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
         : GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
