/*
  This file is part of TALER
  Copyright (C) 2024 Taler Systems SA

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

  TALER 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 Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License along with TALER;
  see the file COPYING.LGPL.  If not, see <http://www.gnu.org/licenses/>
 */
/**
 * @file testing_api_cmd_delete_donau_instances.c
 * @brief Command to test DELETE /donau/$charity_id request
 * @author Bohdan Potuzhnyi
 * @author Vlada Svirsh
 */

#include "platform.h"
#include <taler/taler_testing_lib.h>
#include "taler_merchant_service.h"
#include "taler_merchant_testing_lib.h"
#include "taler_merchant_donau.h"

/**
 * State for DELETE /donau/$charity_id testing command.
 */
struct DeleteDonauState
{
  /**
   * Handle for a DELETE /donau request.
   */
  struct TALER_MERCHANT_DonauInstanceDeleteHandle *ddh;

  /**
   * The interpreter state.
   */
  struct TALER_TESTING_Interpreter *is;

  /**
   * Base URL of the Donau service.
   */
  const char *url;

  /**
   * Charity ID to delete.
   */
  uint64_t charity_id;

  /**
   * Expected HTTP response code.
   */
  unsigned int expected_http_status;
};

/**
 * Callback for DELETE /donau/$charity_id operation.
 *
 * @param cls closure for this function
 * @param hr HTTP response details
 */
static void
delete_donau_cb (void *cls,
                 const struct TALER_MERCHANT_HttpResponse *hr)
{
  struct DeleteDonauState *dds = cls;

  dds->ddh = NULL;

  if (dds->expected_http_status != hr->http_status)
  {
    TALER_TESTING_unexpected_status_with_body (
      dds->is,
      hr->http_status,
      dds->expected_http_status,
      hr->reply);
    TALER_TESTING_interpreter_fail (dds->is);
    return;
  }

  switch (hr->http_status)
  {
  case MHD_HTTP_NO_CONTENT:
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "DELETE /donau succeeded\n");
    break;
  case MHD_HTTP_NOT_FOUND:
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "DELETE /donau: Charity not found\n");
    break;
  case MHD_HTTP_UNAUTHORIZED:
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "DELETE /donau: Unauthorized access\n");
    break;
  default:
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Unhandled HTTP status %u\n",
                hr->http_status);
  }

  TALER_TESTING_interpreter_next (dds->is);
}


/**
 * Run the DELETE /donau/$charity_id test command.
 *
 * @param cls closure.
 * @param cmd command being run now.
 * @param is interpreter state.
 */
static void
delete_donau_run (void *cls,
                  const struct TALER_TESTING_Command *cmd,
                  struct TALER_TESTING_Interpreter *is)
{
  struct DeleteDonauState *dds = cls;

  dds->is = is;
  dds->ddh = TALER_MERCHANT_donau_instance_delete (
    TALER_TESTING_interpreter_get_context (is),
    dds->url,
    dds->charity_id,
    &delete_donau_cb,
    dds);

  if (NULL == dds->ddh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to initiate DELETE /donau/$charity_id\n");
    TALER_TESTING_interpreter_fail (is);
    return;
  }
}


/**
 * Clean up state for DELETE /donau/$charity_id command.
 *
 * @param cls closure.
 * @param cmd command being run.
 */
static void
delete_donau_cleanup (void *cls,
                      const struct TALER_TESTING_Command *cmd)
{
  struct DeleteDonauState *dds = cls;

  if (NULL != dds->ddh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "DELETE /donau/$charity_id operation did not complete\n");
    TALER_MERCHANT_donau_instance_delete_cancel (dds->ddh);
  }
  GNUNET_free (dds);
}


/**
 * Create a DELETE /donau/$charity_id testing command.
 */
struct TALER_TESTING_Command
TALER_TESTING_cmd_merchant_delete_donau_instance (const char *label,
                                                  const char *url,
                                                  uint64_t charity_id,
                                                  unsigned int
                                                  expected_http_status)
{
  struct DeleteDonauState *dds = GNUNET_new (struct DeleteDonauState);

  dds->url = url;
  dds->charity_id = charity_id;
  dds->expected_http_status = expected_http_status;

  {
    struct TALER_TESTING_Command cmd = {
      .cls = dds,
      .label = label,
      .run = &delete_donau_run,
      .cleanup = &delete_donau_cleanup
    };

    return cmd;
  }

}
