/*
 * prop_commands.c:  Implementation of propset, propget, and proplist.
 *
 * ====================================================================
 * Copyright (c) 2000-2002 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

/* ==================================================================== */



/*** Includes. ***/

#define APR_WANT_STRFUNC
#include <apr_want.h>

#include "svn_client.h"
#include "client.h"
#include "svn_path.h"



/*** Code. ***/

svn_error_t *
svn_client_propset (const char *propname,
                    const svn_string_t *propval,
                    const char *target,
                    svn_boolean_t recurse,
                    apr_pool_t *pool)
{
  svn_wc_entry_t *node;

  /* ### be nice to avoid this */
  svn_stringbuf_t *target_buf = svn_stringbuf_create (target, pool);

  SVN_ERR (svn_wc_entry (&node, target_buf, pool));
  if (!node)
    return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, 0, NULL, pool,
                              "'%s' -- not a versioned resource", 
                              target);

  if (recurse && node->kind == svn_node_dir)
    {
      apr_hash_t *entries;
      apr_hash_index_t *hi;
      SVN_ERR (svn_wc_entries_read (&entries, target_buf, pool));

      for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
        {
          const void *key;
          const char *keystring;
          apr_ssize_t klen;
          void * val;
          const char *current_entry_name;
          svn_stringbuf_t *full_entry_path = svn_stringbuf_create (target,
                                                                   pool);
          svn_wc_entry_t *current_entry;

          apr_hash_this (hi, &key, &klen, &val);
          keystring = key;
          current_entry = val;
        
          if (! strcmp (keystring, SVN_WC_ENTRY_THIS_DIR))
              current_entry_name = NULL;
          else
              current_entry_name = keystring;

          /* Compute the complete path of the entry */
          if (current_entry_name)
            svn_path_add_component_nts (full_entry_path, current_entry_name);

          if (current_entry->schedule != svn_wc_schedule_delete)
            {
              if (current_entry->kind == svn_node_dir && current_entry_name)
                {
                  SVN_ERR (svn_client_propset (propname, propval,
                                               full_entry_path->data, recurse,
                                               pool));
                }
              else
                {
                  SVN_ERR (svn_wc_prop_set (propname, propval,
                                            full_entry_path->data, pool));
                }
            }
        }
      
    }
  else
    {
      SVN_ERR (svn_wc_prop_set (propname, propval, target, pool));
    }
  return SVN_NO_ERROR;
}

/* Helper for svn_client_propget. */
static svn_error_t *
recursive_propget (apr_hash_t *props,
                   const char *propname,
                   svn_stringbuf_t *target,
                   apr_pool_t *pool)
{
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  SVN_ERR (svn_wc_entries_read (&entries, target, pool));

  for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      const char *keystring;
      apr_ssize_t klen;
      void * val;
      const char *current_entry_name;
      svn_stringbuf_t *full_entry_path = svn_stringbuf_dup (target, pool);
      svn_wc_entry_t *current_entry;

      apr_hash_this (hi, &key, &klen, &val);
      keystring = key;
      current_entry = val;
    
      if (! strcmp (keystring, SVN_WC_ENTRY_THIS_DIR))
          current_entry_name = NULL;
      else
          current_entry_name = keystring;

      /* Compute the complete path of the entry */
      if (current_entry_name)
        svn_path_add_component_nts (full_entry_path, current_entry_name);

      if (current_entry->schedule != svn_wc_schedule_delete)
        {
          if (current_entry->kind == svn_node_dir && current_entry_name)
            {
              SVN_ERR (recursive_propget (props, propname,
                                          full_entry_path, pool));
            }
          else
            {
              const svn_string_t *propval;
              SVN_ERR (svn_wc_prop_get (&propval,
                                        propname,
                                        full_entry_path->data,
                                        pool));
              if (propval)
                apr_hash_set (props,
                              full_entry_path->data, 
                              full_entry_path->len,
                              propval);
            }
        }
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_propget (apr_hash_t **props,
                    const char *propname,
                    const char *target,
                    svn_boolean_t recurse,
                    apr_pool_t *pool)
{
  apr_hash_t *prop_hash = apr_hash_make (pool);
  svn_wc_entry_t *node;

  /* ### be nice to avoid this */
  svn_stringbuf_t *target_buf = svn_stringbuf_create (target, pool);

  SVN_ERR (svn_wc_entry (&node, target_buf, pool));
  if (!node)
    return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, 0, NULL, pool,
                              "'%s' -- not a versioned resource", target);

  if (recurse && node->kind == svn_node_dir)
    {
      SVN_ERR (recursive_propget (prop_hash, propname, target_buf, pool));
    }
  else
    {
      const svn_string_t *propval;
      SVN_ERR (svn_wc_prop_get (&propval, propname, target, pool));
      if (propval)
        apr_hash_set (prop_hash, target, APR_HASH_KEY_STRING, propval);
    }

  *props = prop_hash;
  return SVN_NO_ERROR;
}

/* Helper for svn_client_proplist, and recursive_proplist. */
static svn_error_t *
add_to_proplist (apr_array_header_t *prop_list,
                 const char *node_name,
                 apr_pool_t *pool)
{
  apr_hash_t *hash;

  SVN_ERR (svn_wc_prop_list (&hash, node_name, pool));

  if (hash && apr_hash_count (hash))
    {
      svn_client_proplist_item_t *item
          = apr_palloc(pool, sizeof(svn_client_proplist_item_t));
      item->node_name = svn_stringbuf_create (node_name, pool);
      item->prop_hash = hash;

      *((svn_client_proplist_item_t **)apr_array_push(prop_list)) = item;
    }

  return SVN_NO_ERROR;
}

/* Helper for svn_client_proplist. */
static svn_error_t *
recursive_proplist (apr_array_header_t *props,
                    svn_stringbuf_t *target,
                    apr_pool_t *pool)
{
  apr_hash_t *entries;
  apr_hash_index_t *hi;

  SVN_ERR (svn_wc_entries_read (&entries, target, pool));

  for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      const char *keystring;
      apr_ssize_t klen;
      void * val;
      const char *current_entry_name;
      svn_stringbuf_t *full_entry_path = svn_stringbuf_dup (target, pool);
      svn_wc_entry_t *current_entry;

      apr_hash_this (hi, &key, &klen, &val);
      keystring = key;
      current_entry = val;
    
      if (! strcmp (keystring, SVN_WC_ENTRY_THIS_DIR))
          current_entry_name = NULL;
      else
          current_entry_name = keystring;

      /* Compute the complete path of the entry */
      if (current_entry_name)
        svn_path_add_component_nts (full_entry_path, current_entry_name);

      if (current_entry->schedule != svn_wc_schedule_delete)
        {
          if (current_entry->kind == svn_node_dir && current_entry_name)
              SVN_ERR (recursive_proplist (props, full_entry_path, pool));
          else
              SVN_ERR (add_to_proplist (props, full_entry_path->data, pool));
        }
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_proplist (apr_array_header_t **props,
                     const char *target, 
                     svn_boolean_t recurse,
                     apr_pool_t *pool)
{
  apr_array_header_t *prop_list
      = apr_array_make (pool, 5, sizeof (svn_client_proplist_item_t *));
  svn_wc_entry_t *entry;

  /* ### be nice to avoid this */
  svn_stringbuf_t *target_buf = svn_stringbuf_create (target, pool);

  SVN_ERR (svn_wc_entry (&entry, target_buf, pool));
  if (! entry)
    return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, 0, NULL, pool,
                              "'%s' -- not a versioned resource", 
                              target);


  if (recurse && entry->kind == svn_node_dir)
      SVN_ERR (recursive_proplist (prop_list, target_buf, pool));
  else 
      SVN_ERR (add_to_proplist (prop_list, target, pool));

  *props = prop_list;
  return SVN_NO_ERROR;
}


/* 
 * local variables:
 * eval: (load-file "../../../tools/dev/svn-dev.el")
 * end: */
