/*
  This file is part of Taler
  Copyright (C) 2018 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,
  write to the Free Software Foundation, Inc., 51 Franklin
  Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef TALER_TWISTER_SERVICE_H_
#define TALER_TWISTER_SERVICE_H_

#define TWISTER_FAIL() \
        do {GNUNET_break (0); return NULL; } while (0)

/**
 * @author Christian Grothoff
 * @author Marcello Stanisci
 */

#ifdef __cplusplus
extern "C"
{
#if 0                   /* keep Emacsens' auto-indent happy */
}
#endif
#endif

#include <gnunet/gnunet_util_lib.h>

/**
 * Version of the twister API.
 */
#define TALER_TWISTER_VERSION 0x00000000

/**
 * Handle for
 */
struct TALER_TWISTER_Handle;


/**
 * Return twister project data.
 */
const struct GNUNET_OS_ProjectData *
TWISTER_project_data (void);


/**
 * Connect to the twister service.
 *
 * @param cfg the configuration to use
 * @return handle to use in #TALER_TWISTER_disconnect to disconnect
 */
struct TALER_TWISTER_Handle *
TALER_TWISTER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);


/**
 * Disconnect from twister service.
 *
 * @param h handle to destroy
 */
void
TALER_TWISTER_disconnect (struct TALER_TWISTER_Handle *h);


/**
 * Opaque handle for asynchronous operation.
 */
struct TALER_TWISTER_Operation;


/**
 * Change the response field pointed by @a modify_path with
 * @a modify_value.
 *
 * @param h twister instance to control
 * @param path object-like notation path to the object to modify
 * @param value value to use for @a modify_path
 * @param cb callback to call once twister gets this instruction.
 * @param cb_cls closure for @a cb_callback
 *
 * @return operation handle.
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_modify_path_dl (struct TALER_TWISTER_Handle *h,
                              const char *path,
                              const char *value,
                              GNUNET_SCHEDULER_TaskCallback cb,
                              void *cb_cls);


/**
 * Change the JSON field pointed by @a path to the new @a value.
 * It only applies to upload objects.
 *
 * @param h twister instance to control
 * @param path object-like notation path to the object to modify
 * @param value value to use for @a modify_path
 * @param cb callback to call once twister gets this instruction.
 * @param cb_cls closure for @a cb_callback
 *
 * @return operation handle.
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_modify_path_ul (struct TALER_TWISTER_Handle *h,
                              const char *path,
                              const char *value,
                              GNUNET_SCHEDULER_TaskCallback cb,
                              void *cb_cls);


/**
 * Change the HTTP response header of @a header to @a value.
 *
 * @param h twister instance to control
 * @param header the HTTP response header to modify
 * @param value value to use for @a header
 * @param cb callback to call once twister gets this instruction.
 * @param cb_cls closure for @a cb_callback
 *
 * @return operation handle.
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_modify_header_dl (struct TALER_TWISTER_Handle *h,
                                const char *header,
                                const char *value,
                                GNUNET_SCHEDULER_TaskCallback cb,
                                void *cb_cls);


/**
 * Instruct the twister to flip a character into
 * the string JSON field that belongs to the object
 * being returned to the HTTP client.
 *
 * @param h twister instance to control
 * @param path object-like notation to point the string
 *        object where we seek a character to flip.
 * @param cb function to call once twister has processed this
 *        request
 * @param cb_cls closure for @a cb
 * @return operation handle (to possibly abort)
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_flip_download (struct TALER_TWISTER_Handle *h,
                             const char *path,
                             GNUNET_SCHEDULER_TaskCallback cb,
                             void *cb_cls);


/**
 * Instruct the twister to flip a character into
 * the string JSON field that belongs to the object
 * being uploaded to the proxied service.
 *
 * @param h twister instance to control
 * @param path object-like notation to point the string
 *        object where we seek a character to flip.
 * @param cb function to call once twister has batched this
 *        request
 * @param cb_cls closure for @a cb
 * @return operation handle (to possibly abort)
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_flip_upload (struct TALER_TWISTER_Handle *h,
                           const char *path,
                           GNUNET_SCHEDULER_TaskCallback cb,
                           void *cb_cls);


/**
 * Change the next response code to @a new_rc.
 *
 * @param h twister instance to control
 * @param new_rc response code to return from the next response
 * @param cb function to call once twister is ready
 * @param cb_cls closure for @a cb
 * @return operation handle (to possibly abort)
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_change_response_code (struct TALER_TWISTER_Handle *h,
                                    unsigned int new_rc,
                                    GNUNET_SCHEDULER_TaskCallback cb,
                                    void *cb_cls);


/**
 * Randomly truncate the response.
 *
 * @param h twister instance to control
 * @param cb function to call once twister has processed this
 *           request.
 * @param cb_cls closure for @a cb
 * @return operation handle (to possibly abort)
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_malform (struct TALER_TWISTER_Handle *h,
                       GNUNET_SCHEDULER_TaskCallback cb,
                       void *cb_cls);


/**
 * Randomly truncate the request.
 *
 * @param h twister instance to control
 * @param cb function to call once twister is ready; typically
 *        a acknowledge function.
 * @param cb_cls closure for @a cb
 * @return operation handle (to possibly abort)
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_malform_upload (struct TALER_TWISTER_Handle *h,
                              GNUNET_SCHEDULER_TaskCallback cb,
                              void *cb_cls);


/**
 * Delete the object pointed to by @a path.  Note, this
 * object belongs to the JSON response object.
 *
 * @param h twister instance to control
 * @param path object-like notation to point the object to be
          deleted.  E.g., the path "f1.f2.0" will delete the object
          {"f1": {"f2": [{"to be": "deleted"}]}}.
 * @param cb function to call once twister is ready
 * @param cb_cls closure for @a cb
 * @return operation handle (to possibly abort)
 */
struct TALER_TWISTER_Operation *
TALER_TWISTER_delete_path (struct TALER_TWISTER_Handle *h,
                           const char *path,
                           GNUNET_SCHEDULER_TaskCallback cb,
                           void *cb_cls);


/**
 * Abort operation.  Twister behavior may then include the
 * changes requested by the operation, or not!  Must be called
 * before the operations callback was invoked.
 *
 * @param op operation to cancel,
 *        operation's callback will not be called
 */
void
TALER_TWISTER_cancel (struct TALER_TWISTER_Operation *op);


#if 0                   /* keep Emacsens' auto-indent happy */
{
#endif
#ifdef __cplusplus
}
#endif


#endif /* TALER_NSE_SERVICE_H_ */
