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

  TALER 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.

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

  You should have received a copy of the GNU General Public
  License along with TALER; see the file COPYING.  If not, see
  <http://www.gnu.org/licenses/>
*/
/**
 * @file testing_api_cmd_kyc_get.c
 * @brief command to test kyc_get request
 * @author Bohdan Potuzhnyi
 * @author Vlada Svirsh
 */
#include "platform.h"
#include <taler/taler_exchange_service.h>
#include <taler/taler_testing_lib.h>
#include "taler_merchant_service.h"
#include "taler_merchant_testing_lib.h"
#include "taler_merchant_donau.h"

/**
 * State of a "GET donau instances" CMD.
 */
struct GetDonauInstancesState
{
  /**
   * Handle for a "GET donau instances" request.
   */
  struct TALER_MERCHANT_DonauInstanceGetHandle *dgh;

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

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

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

  /**
   * The number of instances in the `instances` array.
   */
  unsigned int instances_length;
};

/**
 * Callback for a /get/donau operation.
 *
 * @param cls closure for this function
 * @param response response details from the Donau service
 */
static void
get_donau_instances_cb (void *cls,
                        const struct
                        TALER_MERCHANT_DonauInstanceGetResponse *response)
{
  struct GetDonauInstancesState *gis = cls;

  gis->dgh = NULL;

  if (gis->expected_http_status != response->hr.http_status)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Unexpected response code %u (%d) to command %s\n",
                response->hr.http_status,
                (int) response->hr.ec,
                TALER_TESTING_interpreter_get_current_label (gis->is));
    TALER_TESTING_interpreter_fail (gis->is);
    return;
  }

  if (MHD_HTTP_OK == response->hr.http_status)
  {
    unsigned int instance_count = response->details.ok.donau_instances_length;
    if (instance_count != gis->instances_length)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Expected %u instances, but got %u\n",
                  gis->instances_length, instance_count);
      TALER_TESTING_interpreter_fail (gis->is);
      return;
    }
  }
  TALER_TESTING_interpreter_next (gis->is);
}


/**
 * Run the "GET donau instance" CMD.
 *
 * @param cls closure.
 * @param cmd command being run now.
 * @param is interpreter state.
 */
static void
get_donau_instances_run (void *cls,
                         const struct TALER_TESTING_Command *cmd,
                         struct TALER_TESTING_Interpreter *is)
{
  struct GetDonauInstancesState *gis = cls;

  gis->is = is;
  gis->dgh = TALER_MERCHANT_donau_instances_get (
    TALER_TESTING_interpreter_get_context (is),
    gis->url,
    &get_donau_instances_cb,
    gis);

  GNUNET_assert (NULL != gis->dgh);
}


/**
 * Free the state of a "GET donau instance" CMD, and possibly
 * cancel a pending operation thereof.
 *
 * @param cls closure.
 * @param cmd command being run.
 */
static void
get_donau_instances_cleanup (void *cls,
                             const struct TALER_TESTING_Command *cmd)
{
  struct GetDonauInstancesState *gis = cls;

  if (NULL != gis->dgh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "GET /donau instances operation did not complete\n");
    TALER_MERCHANT_donau_instances_get_cancel (gis->dgh);
  }

  GNUNET_free (gis);
}


/**
 * Creation of the "GET donau instances" CMD.
 */
struct TALER_TESTING_Command
TALER_TESTING_cmd_merchant_get_donau_instances (const char *label,
                                                const char *url,
                                                unsigned int instance_count,
                                                unsigned int
                                                expected_http_status,
                                                ...)
{
  struct GetDonauInstancesState *gis;
  va_list ap;

  gis = GNUNET_new (struct GetDonauInstancesState);
  gis->url = url;
  gis->expected_http_status = expected_http_status;
  gis->instances_length = instance_count;

  va_start (ap, expected_http_status);
  va_end (ap);
  {
    struct TALER_TESTING_Command cmd = {
      .cls = gis,
      .label = label,
      .run = &get_donau_instances_run,
      .cleanup = &get_donau_instances_cleanup
    };
    return cmd;
  }
}
