/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* config-loader-expat.c  expat XML loader
 *
 * Copyright (C) 2003 Red Hat, Inc.
 *
 * Licensed under the Academic Free License version 2.1
 *
 * This program 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 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "config-parser.h"
#include <dbus/dbus-internals.h>
#include <expat.h>

static XML_Memory_Handling_Suite memsuite;

typedef struct
{
  BusConfigParser *parser;
  const char *filename;
  DBusString content;
  DBusError *error;
  dbus_bool_t failed;
} ExpatParseContext;

static dbus_bool_t
process_content (ExpatParseContext *context)
{
  if (context->failed)
    return FALSE;

  if (_dbus_string_get_length (&context->content) > 0)
    {
      if (!bus_config_parser_content (context->parser,
                                      &context->content,
                                      context->error))
        {
          context->failed = TRUE;
          return FALSE;
        }
      _dbus_string_set_length (&context->content, 0);
    }

  return TRUE;
}

static void
expat_StartElementHandler (void            *userData,
                           const XML_Char  *name,
                           const XML_Char **atts)
{
  ExpatParseContext *context = userData;
  int i;
  char **names;
  char **values;

  /* Expat seems to suck and can't abort the parse if we
   * throw an error. Expat 2.0 is supposed to fix this.
   */
  if (context->failed)
    return;

  if (!process_content (context))
    return;

  /* "atts" is key, value, key, value, NULL */
  for (i = 0; atts[i] != NULL; ++i)
    ; /* nothing */

  _dbus_assert (i % 2 == 0);
  names = dbus_new0 (char *, i / 2 + 1);
  values = dbus_new0 (char *, i / 2 + 1);

  if (names == NULL || values == NULL)
    {
      dbus_set_error (context->error, DBUS_ERROR_NO_MEMORY, NULL);
      context->failed = TRUE;
      dbus_free (names);
      dbus_free (values);
      return;
    }

  i = 0;
  while (atts[i] != NULL)
    {
      _dbus_assert (i % 2 == 0);
      names [i / 2] = (char*) atts[i];
      values[i / 2] = (char*) atts[i+1];

      i += 2;
    }

  if (!bus_config_parser_start_element (context->parser,
                                        name,
                                        (const char **) names,
                                        (const char **) values,
                                        context->error))
    {
      dbus_free (names);
      dbus_free (values);
      context->failed = TRUE;
      return;
    }

  dbus_free (names);
  dbus_free (values);
}

static void
expat_EndElementHandler (void           *userData,
                         const XML_Char *name)
{
  ExpatParseContext *context = userData;

  if (!process_content (context))
    return;

  if (!bus_config_parser_end_element (context->parser,
                                      name,
                                      context->error))
    {
      context->failed = TRUE;
      return;
    }
}

/* s is not 0 terminated. */
static void
expat_CharacterDataHandler (void           *userData,
                            const XML_Char *s,
                            int             len)
{
  ExpatParseContext *context = userData;
  if (context->failed)
    return;

  if (!_dbus_string_append_len (&context->content,
                                s, len))
    {
      dbus_set_error (context->error, DBUS_ERROR_NO_MEMORY, NULL);
      context->failed = TRUE;
      return;
    }
}


BusConfigParser*
bus_config_load (const DBusString      *file,
                 dbus_bool_t            is_toplevel,
                 const BusConfigParser *parent,
                 DBusError             *error)
{
  XML_Parser expat;
  const char *filename;
  BusConfigParser *parser;
  ExpatParseContext context;
  DBusString dirname;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  parser = NULL;
  expat = NULL;
  context.error = error;
  context.failed = FALSE;

  filename = _dbus_string_get_const_data (file);

  if (!_dbus_string_init (&context.content))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return NULL;
    }

  if (!_dbus_string_init (&dirname))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      _dbus_string_free (&context.content);
      return NULL;
    }

  memsuite.malloc_fcn = dbus_malloc;
  memsuite.realloc_fcn = dbus_realloc;
  memsuite.free_fcn = dbus_free;

  expat = XML_ParserCreate_MM ("UTF-8", &memsuite, NULL);
  if (expat == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed;
    }

  if (!_dbus_string_get_dirname (file, &dirname))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed;
    }
  
  parser = bus_config_parser_new (&dirname, is_toplevel, parent);
  if (parser == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto failed;
    }
  context.parser = parser;

  XML_SetUserData (expat, &context);
  XML_SetElementHandler (expat,
                         expat_StartElementHandler,
                         expat_EndElementHandler);
  XML_SetCharacterDataHandler (expat,
                               expat_CharacterDataHandler);

  {
    DBusString data;
    const char *data_str;

    if (!_dbus_string_init (&data))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto failed;
      }

    if (!_dbus_file_get_contents (&data, file, error))
      {
        _dbus_string_free (&data);
        goto failed;
      }

    data_str = _dbus_string_get_const_data (&data);

    if (!XML_Parse (expat, data_str, _dbus_string_get_length (&data), TRUE))
      {
        if (context.error != NULL &&
            !dbus_error_is_set (context.error))
          {
            enum XML_Error e;

            e = XML_GetErrorCode (expat);
            if (e == XML_ERROR_NO_MEMORY)
              dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
            else
              dbus_set_error (error, DBUS_ERROR_FAILED,
                              "Error in file %s, line %d, column %d: %s\n",
                              filename,
                              XML_GetCurrentLineNumber (expat),
                              XML_GetCurrentColumnNumber (expat),
                              XML_ErrorString (e));
          }

        _dbus_string_free (&data);
        goto failed;
      }

    _dbus_string_free (&data);

    if (context.failed)
      goto failed;
  }

  if (!bus_config_parser_finished (parser, error))
    goto failed;

  _dbus_string_free (&dirname);
  _dbus_string_free (&context.content);
  XML_ParserFree (expat);

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  return parser;

 failed:
  _DBUS_ASSERT_ERROR_IS_SET (error);

  _dbus_string_free (&dirname);
  _dbus_string_free (&context.content);
  if (expat)
    XML_ParserFree (expat);
  if (parser)
    bus_config_parser_unref (parser);
  return NULL;
}
