/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <glib-object.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>

#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
#include <thrift/c_glib/server/thrift_server.h>
#include <thrift/c_glib/server/thrift_simple_server.h>
#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>

#include "gen-c_glib/calculator.h"

G_BEGIN_DECLS

/* In the C (GLib) implementation of Thrift, the actual work done by a
   server---that is, the code that runs when a client invokes a
   service method---is defined in a separate "handler" class that
   implements the service interface. Here we define the
   TutorialCalculatorHandler class, which implements the CalculatorIf
   interface and provides the behavior expected by tutorial clients.
   (Typically this code would be placed in its own module but for
   clarity this tutorial is presented entirely in a single file.)

   For each service the Thrift compiler generates an abstract base
   class from which handler implementations should inherit. In our
   case TutorialCalculatorHandler inherits from CalculatorHandler,
   defined in gen-c_glib/calculator.h.

   If you're new to GObject, try not to be intimidated by the quantity
   of code here---much of it is boilerplate and can mostly be
   copied-and-pasted from existing work. For more information refer to
   the GObject Reference Manual, available online at
   https://developer.gnome.org/gobject/. */

#define TYPE_TUTORIAL_CALCULATOR_HANDLER \
  (tutorial_calculator_handler_get_type ())

#define TUTORIAL_CALCULATOR_HANDLER(obj)                                \
  (G_TYPE_CHECK_INSTANCE_CAST ((obj),                                   \
                               TYPE_TUTORIAL_CALCULATOR_HANDLER,        \
                               TutorialCalculatorHandler))
#define TUTORIAL_CALCULATOR_HANDLER_CLASS(c)                    \
  (G_TYPE_CHECK_CLASS_CAST ((c),                                \
                            TYPE_TUTORIAL_CALCULATOR_HANDLER,   \
                            TutorialCalculatorHandlerClass))
#define IS_TUTORIAL_CALCULATOR_HANDLER(obj)                             \
  (G_TYPE_CHECK_INSTANCE_TYPE ((obj),                                   \
                               TYPE_TUTORIAL_CALCULATOR_HANDLER))
#define IS_TUTORIAL_CALCULATOR_HANDLER_CLASS(c)                 \
  (G_TYPE_CHECK_CLASS_TYPE ((c),                                \
                            TYPE_TUTORIAL_CALCULATOR_HANDLER))
#define TUTORIAL_CALCULATOR_HANDLER_GET_CLASS(obj)              \
  (G_TYPE_INSTANCE_GET_CLASS ((obj),                            \
                              TYPE_TUTORIAL_CALCULATOR_HANDLER, \
                              TutorialCalculatorHandlerClass))

struct _TutorialCalculatorHandler {
  CalculatorHandler parent_instance;

  /* private */
  GHashTable *log;
};
typedef struct _TutorialCalculatorHandler TutorialCalculatorHandler;

struct _TutorialCalculatorHandlerClass {
  CalculatorHandlerClass parent_class;
};
typedef struct _TutorialCalculatorHandlerClass TutorialCalculatorHandlerClass;

GType tutorial_calculator_handler_get_type (void);

G_END_DECLS

/* ---------------------------------------------------------------- */

/* The implementation of TutorialCalculatorHandler follows. */

G_DEFINE_TYPE (TutorialCalculatorHandler,
               tutorial_calculator_handler,
               TYPE_CALCULATOR_HANDLER);

/* Each of a handler's methods accepts at least two parameters: A
   pointer to the service-interface implementation (the handler object
   itself) and a handle to a GError structure to receive information
   about any error that occurs.

   On success, a handler method returns TRUE. A return value of FALSE
   indicates an error occured and the error parameter has been
   set. (Methods should not return FALSE without first setting the
   error parameter.) */
static gboolean
tutorial_calculator_handler_ping (CalculatorIf  *iface,
                                  GError       **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  puts ("ping()");

  return TRUE;
}

/* Service-method parameters are passed through as parameters to the
   handler method.

   If the service method returns a value an output parameter, _return,
   is additionally passed to the handler method. This parameter should
   be set appropriately before the method returns, whenever it
   succeeds.

   The return value from this method happens to be of a base type,
   i32, but note if a method returns a complex type such as a map or
   list *_return will point to a pre-allocated data structure that
   does not need to be re-allocated and should not be destroyed. */
static gboolean
tutorial_calculator_handler_add (CalculatorIf  *iface,
                                 gint32        *_return,
                                 const gint32   num1,
                                 const gint32   num2,
                                 GError       **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  printf ("add(%d,%d)\n", num1, num2);
  *_return = num1 + num2;

  return TRUE;
}

/* Any handler method can return a ThriftApplicationException to the
   client by setting its error parameter appropriately and returning
   FALSE. See the ThriftApplicationExceptionError enumeration defined
   in thrift_application_exception.h for a list of recognized
   exception types (GError codes).

   If a service method can also throw a custom exception (that is, one
   defined in the .thrift file) an additional output parameter will be
   provided (here, "ouch") to hold an instance of the exception, when
   necessary. Note there will be a separate parameter added for each
   type of exception the method can throw.

   Unlike return values, exception objects are never pre-created; this
   is always the responsibility of the handler method. */
static gboolean
tutorial_calculator_handler_calculate (CalculatorIf      *iface,
                                       gint32            *_return,
                                       const gint32       logid,
                                       const Work        *w,
                                       InvalidOperation **ouch,
                                       GError           **error)
{
  THRIFT_UNUSED_VAR (error);

  TutorialCalculatorHandler *self;

  gint *log_key;
  gchar log_value[12];
  SharedStruct *log_struct;

  gint num1;
  gint num2;
  Operation op;
  gboolean result = TRUE;

  g_return_val_if_fail (IS_TUTORIAL_CALCULATOR_HANDLER (iface),
                        FALSE);
  self = TUTORIAL_CALCULATOR_HANDLER (iface);

  /* Remember: Exception objects are never pre-created */
  g_assert (*ouch == NULL);

  /* Fetch the contents of our Work parameter.

     Note that integer properties of thirty-two bits or fewer in width
     are _always_ of type gint, regardless of the range of values they
     hold. A common error is trying to retrieve, say, a structure
     member defined in the .thrift file as type i16 into a variable of
     type gint16, which will clobber variables adjacent on the
     stack. Remember: If you're retrieving an integer property the
     receiving variable must be of either type gint or gint64, as
     appropriate. */
  g_object_get ((Work *)w,
                "num1", &num1,
                "num2", &num2,
                "op",   &op,
                NULL);

  printf ("calculate(%d,{%d,%d,%d})\n", logid, op, num1, num2);

  switch (op) {
  case OPERATION_ADD:
    *_return = num1 + num2;
    break;

  case OPERATION_SUBTRACT:
    *_return = num1 - num2;
    break;

  case OPERATION_MULTIPLY:
    *_return = num1 * num2;
    break;

  case OPERATION_DIVIDE:
    if (num2 == 0) {
      /* For each custom exception type a subclass of ThriftStruct is
         generated by the Thrift compiler. Throw an exception by
         setting the corresponding output parameter to a new instance
         of its type and returning FALSE. */
      *ouch = g_object_new (TYPE_INVALID_OPERATION,
                            "what", op,
                            "why",  g_strdup ("Cannot divide by 0"),
                            NULL);
      result = FALSE;

      /* Note the call to g_strdup above: All the memory used by a
         ThriftStruct's properties belongs to the object itself and
         will be freed on destruction. Removing this call to g_strdup
         will lead to a segmentation fault as the object tries to
         release memory allocated statically to the program. */
    }
    else {
      *_return = num1 / num2;
    }
    break;

  default:
    *ouch = g_object_new (TYPE_INVALID_OPERATION,
                          "what", op,
                          "why",  g_strdup ("Invalid Operation"),
                          NULL);
    result = FALSE;
  }

  /* On success, log a record of the result to our hash table */
  if (result) {
    log_key = g_malloc (sizeof *log_key);
    *log_key = logid;

    snprintf (log_value, sizeof log_value, "%d", *_return);

    log_struct = g_object_new (TYPE_SHARED_STRUCT,
                               "key",   *log_key,
                               "value",  g_strdup (log_value),
                               NULL);
    g_hash_table_replace (self->log, log_key, log_struct);
  }

  return result;
}

/* A one-way method has the same signature as an equivalent, regular
   method that returns no value. */
static gboolean
tutorial_calculator_handler_zip (CalculatorIf  *iface,
                                 GError       **error)
{
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);

  puts ("zip()");

  return TRUE;
}

/* As specified in the .thrift file (tutorial.thrift), the Calculator
   service extends the SharedService service. Correspondingly, in the
   generated code the Calculator interface, CalculatorIf, extends the
   SharedService interface, SharedServiceIf, and subclasses of
   CalculatorHandler should implement its methods as well.

   Here we provide an implementation for the getStruct method from the
   parent service. */
static gboolean
tutorial_calculator_handler_get_struct (SharedServiceIf  *iface,
                                        SharedStruct    **_return,
                                        const gint32      key32,
                                        GError          **error)
{
  THRIFT_UNUSED_VAR (error);

  gint key = (gint)key32;
  TutorialCalculatorHandler *self;
  SharedStruct *log_struct;
  gint log_key;
  gchar *log_value;

  g_return_val_if_fail (IS_TUTORIAL_CALCULATOR_HANDLER (iface),
                        FALSE);
  self = TUTORIAL_CALCULATOR_HANDLER (iface);

  /* Remember: Complex return types are always pre-created and need
     only be populated */
  g_assert (*_return != NULL);

  printf ("getStruct(%d)\n", key);

  /* If the key exists in our log, return the corresponding logged
     data (or an empty SharedStruct structure if it does not).

     Incidentally, note we _must_ here copy the values from the hash
     table into the return structure. All memory used by the return
     structure belongs to the structure itself and will be freed once
     a response is sent to the client. If we merely freed *_return and
     set it to point to our hash-table entry, that would mean memory
     would be released (effectively, data erased) out of the hash
     table! */
  log_struct = g_hash_table_lookup (self->log, &key);
  if (log_struct != NULL) {
    g_object_get (log_struct,
                  "key",   &log_key,
                  "value", &log_value,
                  NULL);
    g_object_set (*_return,
                  "key",   log_key,
                  "value", g_strdup (log_value),
                  NULL);
  }

  return TRUE;
}

/* TutorialCalculatorHandler's instance finalizer (destructor) */
static void
tutorial_calculator_handler_finalize (GObject *object)
{
  TutorialCalculatorHandler *self =
    TUTORIAL_CALCULATOR_HANDLER (object);

  /* Free our calculation-log hash table */
  g_hash_table_unref (self->log);
  self->log = NULL;

  /* Chain up to the parent class */
  G_OBJECT_CLASS (tutorial_calculator_handler_parent_class)->
    finalize (object);
}

/* TutorialCalculatorHandler's instance initializer (constructor) */
static void
tutorial_calculator_handler_init (TutorialCalculatorHandler *self)
{
  /* Create our calculation-log hash table */
  self->log = g_hash_table_new_full (g_int_hash,
                                     g_int_equal,
                                     g_free,
                                     g_object_unref);
}

/* TutorialCalculatorHandler's class initializer */
static void
tutorial_calculator_handler_class_init (TutorialCalculatorHandlerClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  SharedServiceHandlerClass *shared_service_handler_class =
    SHARED_SERVICE_HANDLER_CLASS (klass);
  CalculatorHandlerClass *calculator_handler_class =
    CALCULATOR_HANDLER_CLASS (klass);

  /* Register our destructor */
  gobject_class->finalize = tutorial_calculator_handler_finalize;

  /* Register our implementations of CalculatorHandler's methods */
  calculator_handler_class->ping =
    tutorial_calculator_handler_ping;
  calculator_handler_class->add =
    tutorial_calculator_handler_add;
  calculator_handler_class->calculate =
    tutorial_calculator_handler_calculate;
  calculator_handler_class->zip =
    tutorial_calculator_handler_zip;

  /* Register our implementation of SharedServiceHandler's method */
  shared_service_handler_class->get_struct =
    tutorial_calculator_handler_get_struct;
}

/* ---------------------------------------------------------------- */

/* That ends the implementation of TutorialCalculatorHandler.
   Everything below is fairly generic code that sets up a minimal
   Thrift server for tutorial clients. */


/* Our server object, declared globally so it is accessible within the
   SIGINT signal handler */
ThriftServer *server = NULL;

/* A flag that indicates whether the server was interrupted with
   SIGINT (i.e. Ctrl-C) so we can tell whether its termination was
   abnormal */
gboolean sigint_received = FALSE;

/* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the
   server */
static void
sigint_handler (int signal_number)
{
  THRIFT_UNUSED_VAR (signal_number);

  /* Take note we were called */
  sigint_received = TRUE;

  /* Shut down the server gracefully */
  if (server != NULL)
    thrift_server_stop (server);
}

int main (void)
{
  TutorialCalculatorHandler *handler;
  CalculatorProcessor *processor;

  ThriftServerTransport *server_transport;
  ThriftTransportFactory *transport_factory;
  ThriftProtocolFactory *protocol_factory;

  struct sigaction sigint_action;

  GError *error;
  int exit_status = 0;

#if (!GLIB_CHECK_VERSION (2, 36, 0))
  g_type_init ();
#endif

  /* Create an instance of our handler, which provides the service's
     methods' implementation */
  handler =
    g_object_new (TYPE_TUTORIAL_CALCULATOR_HANDLER,
                  NULL);

  /* Create an instance of the service's processor, automatically
     generated by the Thrift compiler, which parses incoming messages
     and dispatches them to the appropriate method in the handler */
  processor =
    g_object_new (TYPE_CALCULATOR_PROCESSOR,
                  "handler", handler,
                  NULL);

  /* Create our server socket, which binds to the specified port and
     listens for client connections */
  server_transport =
    g_object_new (THRIFT_TYPE_SERVER_SOCKET,
                  "port", 9090,
                  NULL);

  /* Create our transport factory, used by the server to wrap "raw"
     incoming connections from the client (in this case with a
     ThriftBufferedTransport to improve performance) */
  transport_factory =
    g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY,
                  NULL);

  /* Create our protocol factory, which determines which wire protocol
     the server will use (in this case, Thrift's binary protocol) */
  protocol_factory =
    g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY,
                  NULL);

  /* Create the server itself */
  server =
    g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
                  "processor",                processor,
                  "server_transport",         server_transport,
                  "input_transport_factory",  transport_factory,
                  "output_transport_factory", transport_factory,
                  "input_protocol_factory",   protocol_factory,
                  "output_protocol_factory",  protocol_factory,
                  NULL);

  /* Install our SIGINT handler, which handles Ctrl-C being pressed by
     stopping the server gracefully (not strictly necessary, but a
     nice touch) */
  memset (&sigint_action, 0, sizeof (sigint_action));
  sigint_action.sa_handler = sigint_handler;
  sigint_action.sa_flags = SA_RESETHAND;
  sigaction (SIGINT, &sigint_action, NULL);

  /* Start the server, which will run until its stop method is invoked
     (from within the SIGINT handler, in this case) */
  puts ("Starting the server...");
  thrift_server_serve (server, &error);

  /* If the server stopped for any reason other than having been
     interrupted by the user, report the error */
  if (!sigint_received) {
    g_message ("thrift_server_serve: %s",
               error != NULL ? error->message : "(null)");
    g_clear_error (&error);
  }

  puts ("done.");

  g_object_unref (server);
  g_object_unref (transport_factory);
  g_object_unref (protocol_factory);
  g_object_unref (server_transport);

  g_object_unref (processor);
  g_object_unref (handler);

  return exit_status;
}
