/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* config-parser-trivial.c  XML-library-agnostic configuration file parser
 *                  Does not do includes or anything remotely complicated.
 *
 * Copyright (C) 2003, 2004, 2007 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-common.h"
#include "config-parser-trivial.h"
#include "utils.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-internals.h>
#include <string.h>

/**
 * TRIVIAL parser for bus configuration file.
 */
struct BusConfigParser
{
  ElementType type;
  DBusString user;                  /**< User the dbus-daemon runs as */
  DBusString bus_type;              /**< Message bus type */
  DBusString service_helper;        /**< Location of the setuid helper */
  DBusList *service_dirs;           /**< Directories to look for services in */
};

static dbus_bool_t
service_dirs_find_dir (DBusList **service_dirs,
                       const char *dir)
{
  DBusList *link;

  _dbus_assert (dir != NULL);

  for (link = *service_dirs; link; link = _dbus_list_get_next_link(service_dirs, link))
    {
      const char *link_dir;

      link_dir = (const char *)link->data;
      if (strcmp (dir, link_dir) == 0)
        return TRUE;
    }

  return FALSE;
}

static void
service_dirs_append_link_unique_or_free (DBusList **service_dirs,
                                         DBusList *dir_link)
{
  if (!service_dirs_find_dir (service_dirs, dir_link->data))
    {
      _dbus_list_append_link (service_dirs, dir_link);
    }
  else
    {
      dbus_free (dir_link->data);
      _dbus_list_free_link (dir_link);
    }
}

BusConfigParser*
bus_config_parser_new (const DBusString             *basedir,
                       dbus_bool_t                   is_toplevel,
                       const BusConfigParser        *parent)
{
  BusConfigParser *parser;

  parser = dbus_new0 (BusConfigParser, 1);
  if (parser == NULL)
    goto failed;

  parser->type = ELEMENT_NONE;

  /* init the lists */
  parser->service_dirs = NULL;

  /* init the strings */
  if (!_dbus_string_init (&parser->user))
    goto failed_parser;
  if (!_dbus_string_init (&parser->bus_type))
    goto failed_type;
  if (!_dbus_string_init (&parser->service_helper))
    goto failed_helper;

  /* woot! */
  return parser;

/* argh. we have do do this carefully because of OOM */
failed_helper:
  _dbus_string_free (&parser->bus_type);
failed_type:
  _dbus_string_free (&parser->user);
failed_parser:
  dbus_free (parser);
failed:
  return NULL;
}

void
bus_config_parser_unref (BusConfigParser *parser)
{
  _dbus_string_free (&parser->user);
  _dbus_string_free (&parser->service_helper);
  _dbus_string_free (&parser->bus_type);

  _dbus_list_foreach (&parser->service_dirs,
                      (DBusForeachFunction) dbus_free,
                      NULL);

  _dbus_list_clear (&parser->service_dirs);

  dbus_free (parser);
}

dbus_bool_t
bus_config_parser_check_doctype (BusConfigParser   *parser,
                                 const char        *doctype,
                                 DBusError         *error)
{
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  if (strcmp (doctype, "busconfig") != 0)
    {
      dbus_set_error (error,
                      DBUS_ERROR_FAILED,
                      "Configuration file has the wrong document type %s",
                      doctype);
      return FALSE;
    }
  else
    return TRUE;
}

dbus_bool_t
bus_config_parser_start_element (BusConfigParser   *parser,
                                 const char        *element_name,
                                 const char       **attribute_names,
                                 const char       **attribute_values,
                                 DBusError         *error)
{
  /* we don't do processing of attribute names, we don't need to */
  parser->type = bus_config_parser_element_name_to_type (element_name);

  switch (parser->type)
    {
    case ELEMENT_SERVICEHELPER:
    case ELEMENT_USER:
    case ELEMENT_CONFIGTYPE:
      /* content about to be handled */
      break;

    case ELEMENT_STANDARD_SYSTEM_SERVICEDIRS:
      {
        DBusList *link;
        DBusList *dirs;
        dirs = NULL;

        if (!_dbus_get_standard_system_servicedirs (&dirs))
          {
            BUS_SET_OOM (error);
            return FALSE;
          }

          while ((link = _dbus_list_pop_first_link (&dirs)))
            service_dirs_append_link_unique_or_free (&parser->service_dirs, link);
        break;
      }

    default:
      {
        /* we really don't care about the others... */
        _dbus_verbose (" START We dont care about '%s' type '%i'\n", element_name, parser->type);
        break;
      }
    }
  return TRUE;
}

dbus_bool_t
bus_config_parser_end_element (BusConfigParser   *parser,
                               const char               *element_name,
                               DBusError                *error)
{
  /* we don't care */
  return TRUE;
}

dbus_bool_t
bus_config_parser_content (BusConfigParser   *parser,
                           const DBusString  *content,
                           DBusError         *error)
{
  DBusString content_sane;
  dbus_bool_t retval;

  retval = FALSE;

  if (!_dbus_string_init (&content_sane))
    {
      BUS_SET_OOM (error);
      goto out;
    }
  if (!_dbus_string_copy (content, 0, &content_sane, 0))
    {
      BUS_SET_OOM (error);
      goto out_content;
    }

  /* rip out white space */
  _dbus_string_chop_white (&content_sane);
  if (_dbus_string_get_length (&content_sane) == 0)
    {
      /* optimise, there is no content */
      retval = TRUE;
      goto out_content;
    }

  switch (parser->type)
    {
    case ELEMENT_SERVICEDIR:
      {
      	char *cpath;

        /* copy the sane data into a char array */
        if (!_dbus_string_copy_data(&content_sane, &cpath))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }

        /* append the dynamic char string to service dirs */
        if (!_dbus_list_append (&parser->service_dirs, cpath))
          {
            dbus_free (cpath);
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;

    case ELEMENT_SERVICEHELPER:
      {
        if (!_dbus_string_copy (&content_sane, 0, &parser->service_helper, 0))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;

    case ELEMENT_USER:
      {
        if (!_dbus_string_copy (&content_sane, 0, &parser->user, 0))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;

    case ELEMENT_CONFIGTYPE:
      {
        if (!_dbus_string_copy (&content_sane, 0, &parser->bus_type, 0))
          {
            BUS_SET_OOM (error);
            goto out_content;
          }
      }
      break;
    default:
      {
        /* we don't care about the others... really */
        _dbus_verbose (" CONTENTS We dont care '%s' type '%i'\n", _dbus_string_get_const_data (&content_sane), parser->type);
        break;
      }
    }

  /* woot! */
  retval = TRUE;

out_content:
  _dbus_string_free (&content_sane);
out:
  return retval;
}

dbus_bool_t
bus_config_parser_finished (BusConfigParser   *parser,
                            DBusError         *error)
{
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  _dbus_verbose ("finished scanning!\n");
  return TRUE;
}

const char*
bus_config_parser_get_user (BusConfigParser *parser)
{
  return _dbus_string_get_const_data (&parser->user);
}

const char*
bus_config_parser_get_type (BusConfigParser *parser)
{
  return _dbus_string_get_const_data (&parser->bus_type);
}

DBusList**
bus_config_parser_get_service_dirs (BusConfigParser *parser)
{
  return &parser->service_dirs;
}

#ifdef DBUS_BUILD_TESTS
#include <stdio.h>
#include "test.h"

typedef enum
{
  VALID,
  INVALID,
  UNKNOWN
} Validity;

static dbus_bool_t
check_return_values (const DBusString *full_path)
{
  BusConfigParser *parser;
  DBusError error;
  dbus_bool_t retval;
  const char *user;
  const char *type;
  DBusList **dirs;

  dbus_error_init (&error);
  retval = FALSE;

  printf ("Testing values from: %s\n", _dbus_string_get_const_data (full_path));

  parser = bus_config_load (full_path, TRUE, NULL, &error);
  if (parser == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);
      if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
        _dbus_verbose ("Failed to load valid file due to OOM\n");
      goto finish;
    }
  _DBUS_ASSERT_ERROR_IS_CLEAR (&error);

  /* check user return value is okay */
  user = bus_config_parser_get_user (parser);
  if (user == NULL)
    {
      _dbus_warn ("User was NULL!\n");
      goto finish;
    }
#if 0
  /* the username can be configured in configure.in so this test doesn't work */
  if (strcmp (user, "dbus") != 0)
    {
      _dbus_warn ("User was invalid; '%s'!\n", user);
      goto finish;
    }
  printf ("    <user>dbus</user> OKAY!\n");  
#endif
  
  /* check type return value is okay */
  type = bus_config_parser_get_type (parser);
  if (type == NULL)
    {
      _dbus_warn ("Type was NULL!\n");
      goto finish;
    }
  if (strcmp (type, "system") != 0)
    {
      _dbus_warn ("Type was invalid; '%s'!\n", user);
      goto finish;
    }
  printf ("    <type>system</type> OKAY!\n");

  /* check dirs return value is okay */
  dirs = bus_config_parser_get_service_dirs (parser);
  if (dirs == NULL)
    {
      _dbus_warn ("Service dirs are NULL!\n");
      goto finish;
    }
  printf ("    <standard_system_service_dirs/> OKAY!\n");
  /* NOTE: We tested the specific return values in the config-parser tests */

  /* woohoo! */
  retval = TRUE;
finish:
  if (parser != NULL)
    bus_config_parser_unref (parser);
  dbus_error_free (&error);
  return retval;
}

static dbus_bool_t
do_load (const DBusString *full_path,
         Validity          validity,
         dbus_bool_t       oom_possible)
{
  BusConfigParser *parser;
  DBusError error;

  dbus_error_init (&error);

  parser = bus_config_load (full_path, TRUE, NULL, &error);
  if (parser == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);

      if (oom_possible &&
          dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
        {
          _dbus_verbose ("Failed to load valid file due to OOM\n");
          dbus_error_free (&error);
          return TRUE;
        }
      else if (validity == VALID)
        {
          _dbus_warn ("Failed to load valid file but still had memory: %s\n",
                      error.message);

          dbus_error_free (&error);
          return FALSE;
        }
      else
        {
          dbus_error_free (&error);
          return TRUE;
        }
    }
  else
    {
      _DBUS_ASSERT_ERROR_IS_CLEAR (&error);

      bus_config_parser_unref (parser);

      if (validity == INVALID)
        {
          _dbus_warn ("Accepted invalid file\n");
          return FALSE;
        }

      return TRUE;
    }
}

typedef struct
{
  const DBusString *full_path;
  Validity          validity;
} LoaderOomData;

static dbus_bool_t
check_loader_oom_func (void *data)
{
  LoaderOomData *d = data;

  return do_load (d->full_path, d->validity, TRUE);
}

static dbus_bool_t
process_test_valid_subdir (const DBusString *test_base_dir,
                           const char       *subdir,
                           Validity          validity)
{
  DBusString test_directory;
  DBusString filename;
  DBusDirIter *dir;
  dbus_bool_t retval;
  DBusError error;

  retval = FALSE;
  dir = NULL;

  if (!_dbus_string_init (&test_directory))
    _dbus_assert_not_reached ("didn't allocate test_directory\n");

  _dbus_string_init_const (&filename, subdir);

  if (!_dbus_string_copy (test_base_dir, 0,
                          &test_directory, 0))
    _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");

  if (!_dbus_concat_dir_and_file (&test_directory, &filename))
    _dbus_assert_not_reached ("couldn't allocate full path");

  _dbus_string_free (&filename);
  if (!_dbus_string_init (&filename))
    _dbus_assert_not_reached ("didn't allocate filename string\n");

  dbus_error_init (&error);
  dir = _dbus_directory_open (&test_directory, &error);
  if (dir == NULL)
    {
      _dbus_warn ("Could not open %s: %s\n",
                  _dbus_string_get_const_data (&test_directory),
                  error.message);
      dbus_error_free (&error);
      goto failed;
    }

  if (validity == VALID)
    printf ("Testing valid files:\n");
  else if (validity == INVALID)
    printf ("Testing invalid files:\n");
  else
    printf ("Testing unknown files:\n");

 next:
  while (_dbus_directory_get_next_file (dir, &filename, &error))
    {
      DBusString full_path;
      LoaderOomData d;

      if (!_dbus_string_init (&full_path))
        _dbus_assert_not_reached ("couldn't init string");

      if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
        _dbus_assert_not_reached ("couldn't copy dir to full_path");

      if (!_dbus_concat_dir_and_file (&full_path, &filename))
        _dbus_assert_not_reached ("couldn't concat file to dir");

      if (!_dbus_string_ends_with_c_str (&full_path, ".conf"))
        {
          _dbus_verbose ("Skipping non-.conf file %s\n",
                         _dbus_string_get_const_data (&filename));
          _dbus_string_free (&full_path);
          goto next;
        }

      printf ("    %s\n", _dbus_string_get_const_data (&filename));

      _dbus_verbose (" expecting %s\n",
                     validity == VALID ? "valid" :
                     (validity == INVALID ? "invalid" :
                      (validity == UNKNOWN ? "unknown" : "???")));

      d.full_path = &full_path;
      d.validity = validity;

      /* FIXME hackaround for an expat problem, see
       * https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=124747
       * http://freedesktop.org/pipermail/dbus/2004-May/001153.html
       */
      /* if (!_dbus_test_oom_handling ("config-loader", check_loader_oom_func, &d)) */
      if (!check_loader_oom_func (&d))
        _dbus_assert_not_reached ("test failed");
      
      _dbus_string_free (&full_path);
    }

  if (dbus_error_is_set (&error))
    {
      _dbus_warn ("Could not get next file in %s: %s\n",
                  _dbus_string_get_const_data (&test_directory),
                  error.message);
      dbus_error_free (&error);
      goto failed;
    }

  retval = TRUE;

 failed:

  if (dir)
    _dbus_directory_close (dir);
  _dbus_string_free (&test_directory);
  _dbus_string_free (&filename);

  return retval;
}

/* convenience function, do not reuse outside of TEST */
static dbus_bool_t
make_full_path (const DBusString *test_data_dir,
			          const char       *subdir,
			          const char       *file,
			          DBusString       *full_path)
{
  DBusString filename;
  dbus_bool_t retval;

  retval = FALSE;

  if (!_dbus_string_init (full_path))
    {
      _dbus_warn ("couldn't allocate full path");
      goto finish;
    }

  if (!_dbus_string_copy (test_data_dir, 0, full_path, 0))
    {
      _dbus_warn ("couldn't allocate full path");
      goto finish;
    }

  _dbus_string_init_const (&filename, subdir);
  if (!_dbus_concat_dir_and_file (full_path, &filename))
    {
      _dbus_warn ("couldn't allocate full path");
      goto finish;
    }
  _dbus_string_free (&filename);

  _dbus_string_init_const (&filename, file);
  if (!_dbus_concat_dir_and_file (full_path, &filename))
    {
      _dbus_warn ("couldn't allocate full path");
      goto finish;
    }

  /* woot! */
  retval = TRUE;

finish:
  _dbus_string_free (&filename);
  return retval;
}

static dbus_bool_t
check_file_valid (DBusString *full_path,
			            Validity    validity)
{
  dbus_bool_t retval;

  if (validity == VALID)
    printf ("Testing valid file:\n");
  else if (validity == INVALID)
    printf ("Testing invalid file:\n");
  else
    printf ("Testing unknown file:\n");

  /* print the filename, just so we match the other output */
  printf ("    %s\n", _dbus_string_get_const_data (full_path));

  /* only test one file */
  retval = do_load (full_path, validity, TRUE);

  return retval;
}

dbus_bool_t
bus_config_parser_trivial_test (const DBusString *test_data_dir)
{
  DBusString full_path;
  dbus_bool_t retval;

  retval = FALSE;

  if (test_data_dir == NULL ||
      _dbus_string_get_length (test_data_dir) == 0)
    {
      printf ("No test data\n");
      return TRUE;
    }
  
  /* We already test default_session_servicedirs and default_system_servicedirs
   * in bus_config_parser_test() */
  if (!process_test_valid_subdir (test_data_dir, "valid-config-files", VALID))
    goto finish;

  /* we don't process all the invalid files, as the trivial parser can't hope
   * to validate them all for all different syntaxes. We just check one broken
   * file to see if junk is received */
  if (!make_full_path (test_data_dir, "invalid-config-files", "not-well-formed.conf", &full_path))
    goto finish;
  if (!check_file_valid (&full_path, INVALID))
    goto finish;
  _dbus_string_free (&full_path);

  /* just test if the check_file_valid works okay and we got sane values */
  if (!make_full_path (test_data_dir, "valid-config-files", "system.conf", &full_path))
    goto finish;
  if (!check_file_valid (&full_path, VALID))
    goto finish;
  /* check to see if we got the correct values from the parser */
  if (!check_return_values (&full_path))
    goto finish;

  /* woot! */
  retval = TRUE;

finish:
  _dbus_string_free (&full_path);

  /* we don't process equiv-config-files as we don't handle <include> */
  return retval;
}

#endif /* DBUS_BUILD_TESTS */

