/*
     This file is part of libmicrohttpd
     Copyright (C) 2016 Christian Grothoff
     Copyright (C) 2016-2022 Evgeny Grin (Karlson2k)

     libmicrohttpd 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 2, or (at your
     option) any later version.

     libmicrohttpd 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 libmicrohttpd; see the file COPYING.  If not, write to the
     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     Boston, MA 02110-1301, USA.
*/
/**
 * @file test_quiesce_stream.c
 * @brief  Testcase for libmicrohttpd quiescing
 * @author Markus Doppelbauer
 * @author Christian Grothoff
 * @author Karlson2k (Evgeny Grin)
 */
#include "mhd_options.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <microhttpd.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#elif defined(_WIN32)
#include <windows.h>
#define sleep(s) (Sleep ((s) * 1000), 0)
#endif /* _WIN32 */


static volatile unsigned int request_counter;


static void
http_PanicCallback (void *cls,
                    const char *file,
                    unsigned int line,
                    const char *reason)
{
  (void) cls;    /* Unused. Silent compiler warning. */
  fprintf (stderr,
           "PANIC: exit process: %s at %s:%u\n",
           reason,
           file,
           line);
  exit (EXIT_FAILURE);
}


static void *
resume_connection (void *arg)
{
  struct MHD_Connection *connection = arg;

  /* fprintf (stderr, "Calling resume\n"); */
  MHD_resume_connection (connection);
  return NULL;
}


static void
suspend_connection (struct MHD_Connection *connection)
{
  pthread_t thread_id;
  int status;

  /* fprintf (stderr, "Calling suspend\n"); */
  MHD_suspend_connection (connection);
  status = pthread_create (&thread_id,
                           NULL,
                           &resume_connection,
                           connection);
  if (0 != status)
  {
    fprintf (stderr,
             "Could not create thead\n");
    exit (EXIT_FAILURE);
  }
  pthread_detach (thread_id);
}


struct ContentReaderUserdata
{
  size_t bytes_written;
  struct MHD_Connection *connection;
};


static ssize_t
http_ContentReaderCallback (void *cls,
                            uint64_t pos,
                            char *buf,
                            size_t max)
{
  static const char alphabet[] =
    "\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  struct ContentReaderUserdata *userdata = cls;
  (void) pos; (void) max;  /* Unused. Silent compiler warning. */

  if (userdata->bytes_written >= 1024)
  {
    fprintf (stderr,
             "finish: %u\n",
             request_counter);
    return MHD_CONTENT_READER_END_OF_STREAM;
  }
  userdata->bytes_written++;
  buf[0] = alphabet[userdata->bytes_written % (sizeof(alphabet) - 1)];
  suspend_connection (userdata->connection);

  return 1;
}


static void
free_crc_data (void *crc_data)
{
  struct ContentReaderUserdata *userdata = crc_data;

  free (userdata);
}


static enum MHD_Result
http_AccessHandlerCallback (void *cls,
                            struct MHD_Connection *connection,
                            const char *url,
                            const char *method,
                            const char *version,
                            const char *upload_data,
                            size_t *upload_data_size,
                            void **req_cls)
{
  enum MHD_Result ret;
  struct MHD_Response *response;
  (void) cls; (void) url;                        /* Unused. Silent compiler warning. */
  (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
  (void) upload_data_size;                       /* Unused. Silent compiler warning. */

  /* Never respond on first call */
  if (NULL == *req_cls)
  {
    struct ContentReaderUserdata *userdata;
    fprintf (stderr,
             "start: %u\n",
             ++request_counter);

    userdata = malloc (sizeof(struct ContentReaderUserdata));

    if (NULL == userdata)
      return MHD_NO;
    userdata->bytes_written = 0;
    userdata->connection = connection;
    *req_cls = userdata;
    return MHD_YES;
  }

  /* Second call: create response */
  response
    = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
                                         32 * 1024,
                                         &http_ContentReaderCallback,
                                         *req_cls,
                                         &free_crc_data);
  ret = MHD_queue_response (connection,
                            MHD_HTTP_OK,
                            response);
  MHD_destroy_response (response);

  suspend_connection (connection);
  return ret;
}


int
main (void)
{
  uint16_t port;
  char command_line[1024];
  /* Flags */
  unsigned int daemon_flags
    = MHD_USE_INTERNAL_POLLING_THREAD
      | MHD_USE_AUTO
      | MHD_ALLOW_SUSPEND_RESUME
      | MHD_USE_ITC;
  struct MHD_Daemon *daemon;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    port = 1470;

  /* Panic callback */
  MHD_set_panic_func (&http_PanicCallback,
                      NULL);


  /* Create daemon */
  daemon = MHD_start_daemon (daemon_flags,
                             port,
                             NULL,
                             NULL,
                             &http_AccessHandlerCallback,
                             NULL,
                             MHD_OPTION_END);
  if (NULL == daemon)
    return 1;
  if (0 == port)
  {
    const union MHD_DaemonInfo *dinfo;
    dinfo = MHD_get_daemon_info (daemon, MHD_DAEMON_INFO_BIND_PORT);
    if ((NULL == dinfo) || (0 == dinfo->port) )
    {
      MHD_stop_daemon (daemon); return 32;
    }
    port = dinfo->port;
  }
  snprintf (command_line,
            sizeof (command_line),
            "curl -s http://127.0.0.1:%u",
            (unsigned int) port);

  if (0 != system (command_line))
  {
    MHD_stop_daemon (daemon);
    return 1;
  }
  /* wait for a request */
  while (0 == request_counter)
    (void) sleep (1);

  fprintf (stderr,
           "quiesce\n");
  MHD_quiesce_daemon (daemon);

  /* wait a second */
  (void) sleep (1);

  fprintf (stderr,
           "stopping daemon\n");
  MHD_stop_daemon (daemon);

  return 0;
}
