/*
 * commit-drive.c:  Driver for the WC commit process.
 *
 * ====================================================================
 * 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/.
 * ====================================================================
 */

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


#include <string.h>

#include "apr_pools.h"
#include "apr_hash.h"

#include "client.h"
#include "svn_path.h"
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_wc.h"
#include "svn_sorts.h"

#include <assert.h>
#include <stdlib.h>  /* for qsort() */



/*** Uncomment this to turn on commit driver debugging. ***/
/*
#define SVN_CLIENT_COMMIT_DEBUG
*/




/*** Harvesting Commit Candidates ***/


/* If DIR isn't already in the LOCKED_DIRS hash, attempt to lock it.
   If the lock is successful, add DIR to the LOCKED_DIRS hash.  Use
   the hash's pool for adding new items, and POOL for any other
   allocations. */
static svn_error_t *
lock_dir (apr_hash_t *locked_dirs,
          svn_stringbuf_t *dir,
          apr_pool_t *pool)
{
  apr_pool_t *hash_pool = apr_hash_pool_get (locked_dirs);

  if (! apr_hash_get (locked_dirs, dir->data, dir->len))
    {
      SVN_ERR (svn_wc_lock (dir, 0, pool));
      apr_hash_set (locked_dirs, apr_pstrdup (hash_pool, dir->data), 
                    dir->len, (void *)1);
    }
  return SVN_NO_ERROR;
}


/* Add a new commit candidate (described by all parameters except
   `COMMITTABLES') to the COMMITABLES hash. */
static void
add_committable (apr_hash_t *committables,
                 svn_stringbuf_t *path,
                 svn_node_kind_t kind,
                 svn_stringbuf_t *url,
                 svn_revnum_t revision,
                 svn_stringbuf_t *copyfrom_url,
                 apr_byte_t state_flags)
{
  apr_pool_t *pool = apr_hash_pool_get (committables);
  const char *repos_name = SVN_CLIENT__SINGLE_REPOS_NAME;
  apr_array_header_t *array;
  svn_client_commit_item_t *new_item;

  /* Sanity checks. */
  assert (path && url);

  /* ### todo: Get the canonical repository for this item, which will
     be the real key for the COMMITTABLES hash, instead of the above
     bogosity. */
  array = apr_hash_get (committables, repos_name, APR_HASH_KEY_STRING);

  /* E-gads!  There is no array for this repository yet!  Oh, no
     problem, we'll just create (and add to the hash) one. */
  if (array == NULL)
    {
      array = apr_array_make (pool, 1, sizeof (new_item));
      apr_hash_set (committables, repos_name, APR_HASH_KEY_STRING, array);
    }

  /* Now update pointer values, ensuring that their allocations live
     in POOL. */
  new_item = apr_pcalloc (pool, sizeof (*new_item));
  new_item->path         = svn_stringbuf_dup (path, pool);
  new_item->kind         = kind;
  new_item->url          = svn_stringbuf_dup (url, pool);
  new_item->revision     = revision;
  new_item->copyfrom_url = copyfrom_url 
                           ? svn_stringbuf_dup (copyfrom_url, pool)
                           : NULL;
  new_item->state_flags  = state_flags;
   
  /* Now, add the commit item to the array. */
  (*((svn_client_commit_item_t **) apr_array_push (array))) = new_item;
}



/* Recursively search for commit candidates in (and under) PATH (with
   entry ENTRY and ancestry URL), and add those candidates to
   COMMITTABLES.  If in ADDS_ONLY modes, only new additions are
   recognized.  COPYFROM_URL is the default copyfrom-url for children
   of copied directories.

   If in COPY_MODE, the entry is treated as if it is destined to be
   added with history as URL.  */
static svn_error_t *
harvest_committables (apr_hash_t *committables,
                      apr_hash_t *locked_dirs,
                      svn_stringbuf_t *path,
                      svn_stringbuf_t *url,
                      svn_stringbuf_t *copyfrom_url,
                      svn_wc_entry_t *entry,
                      svn_boolean_t adds_only,
                      svn_boolean_t copy_mode,
                      apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create (pool);
  apr_hash_t *entries = NULL;
  svn_boolean_t text_mod = FALSE, prop_mod = FALSE;
  apr_byte_t state_flags = 0;
  svn_stringbuf_t *p_path = svn_stringbuf_dup (path, pool);
  svn_boolean_t tconflict, pconflict;
  svn_stringbuf_t *cf_url = NULL;

  assert (entry);
  assert (url);

  /* Make P_PATH the parent dir. */
  svn_path_remove_component (p_path);

  /* Return error on unknown path kinds. */
  if ((entry->kind != svn_node_file) && (entry->kind != svn_node_dir))
    return svn_error_create 
      (SVN_ERR_UNKNOWN_NODE_KIND, 0, NULL, pool, path->data);

  /* If this is a directory ... */
  if (entry->kind == svn_node_dir)
    { 
      /* ... then try to read its own entries file so we have a full
         entry for it (we were going to have to do this eventually to
         recurse anyway, so... ) */
      svn_wc_entry_t *e = NULL;
      if (svn_wc_entries_read (&entries, path, subpool))
        entries = NULL;

      if ((entries) 
          && ((e = apr_hash_get (entries, SVN_WC_ENTRY_THIS_DIR, 
                                 APR_HASH_KEY_STRING))))
        entry = e;
    }

  /* Test for a state of conflict, returning an error if an unresolved
     conflict exists for this item. */
  SVN_ERR (svn_wc_conflicted_p (&tconflict, &pconflict, p_path, 
                                entry, subpool));
  if (tconflict || pconflict)
    return svn_error_createf (SVN_ERR_WC_FOUND_CONFLICT, 0, NULL, pool,
                              "Aborting commit: '%s' remains in conflict.",
                              path->data);

  /* If we have our own URL, and we're NOT in COPY_MODE, it wins over
     the telescoping one(s).  In COPY_MODE, URL will always be the
     URL-to-be of the copied item.  */
  if ((entry->url) && (! copy_mode))
    url = entry->url;

  /* Check for the deletion case.  Deletes can occur only when we are
     not in "adds-only mode".  They can be either explicit
     (schedule==delete) or implicit (schedule==replace==delete+add).  */
  if ((! adds_only)
      && ((entry->schedule == svn_wc_schedule_delete)
          || (entry->schedule == svn_wc_schedule_replace)))
    {
      state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE;
    }

  /* Check for the trivial addition case.  Adds can be explicit
     (schedule==add) or implicit (schedule==replace==delete+add).  We
     also note whether or not this is an add with history here.  */
  if ((entry->schedule == svn_wc_schedule_add)
      || (entry->schedule == svn_wc_schedule_replace))
    {
      state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
      if (entry->copyfrom_url)
        {
          state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
          cf_url = entry->copyfrom_url;
          adds_only = FALSE;
        }
      else
        {
          adds_only = TRUE;
        }
    }

  /* Check for the copied-subtree addition case.  */
  if ((entry->copied || copy_mode) 
      && (entry->schedule == svn_wc_schedule_normal))
    {
#if 0 /* ### todo: Find a better way to do this that doesn't require
         reading the parent's entry. */
      svn_revnum_t p_rev = entry->revision - 1; /* arbitrary non-equal value */
      svn_boolean_t wc_root = FALSE;

      /* If this is not a WC root then its parent's revision is
         admissible for comparitive purposes. */
      SVN_ERR (svn_wc_is_wc_root (&wc_root, path, subpool));
      if (! wc_root)
        {
          svn_wc_entry_t *p_entry;
          SVN_ERR (svn_wc_entry (&p_entry, p_path, subpool));
          p_rev = p_entry->revision;
        }
      else if (! copy_mode)
        return svn_error_createf 
          (SVN_ERR_WC_CORRUPT, 0, NULL, subpool,
           "Did not expect `%s' to be a working copy root", path->data);

      if (entry->revision != p_rev)
#endif /* 0 */
        {
          state_flags |= SVN_CLIENT_COMMIT_ITEM_ADD;
          state_flags |= SVN_CLIENT_COMMIT_ITEM_IS_COPY;
          adds_only = TRUE;
          if (copy_mode)
            cf_url = entry->url;
          else
            cf_url = copyfrom_url;
        }
    }

  /* If an add is scheduled to occur, dig around for some more
     information about it. */
  if (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
    {
      /* See if there are property modifications to send. */
      SVN_ERR (svn_wc_props_modified_p (&prop_mod, path, subpool));

      /* Regular adds of files have text mods, but for copies we have
         to test for textual mods.  Directories simply don't have text! */
      if (entry->kind == svn_node_file)
        {
          if (state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
            SVN_ERR (svn_wc_text_modified_p (&text_mod, path, subpool));
          else
            text_mod = TRUE;
        }
    }

  /* Else, if we aren't deleting this item, we'll have to look for
     local text or property mods to determine if the path might be
     committable. */
  else if (! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
    {
      /* Check for local mods: text+props for files, props alone for dirs. */
      if (entry->kind == svn_node_file)
        SVN_ERR (svn_wc_text_modified_p (&text_mod, path, subpool));
      SVN_ERR (svn_wc_props_modified_p (&prop_mod, path, subpool));
    }

  /* Set text/prop modification flags accordingly. */
  if (text_mod)
    state_flags |= SVN_CLIENT_COMMIT_ITEM_TEXT_MODS;
  if (prop_mod)
    state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;

  /* Now, if this is something to commit, add it to our list. */
  if (state_flags)
    {
      /* If the commit item is a directory, lock it, else lock its parent. */
      if (entry->kind == svn_node_dir)
        lock_dir (locked_dirs, path, pool);
      else
        lock_dir (locked_dirs, p_path, pool);

      /* Finally, add the committable item. */
      add_committable (committables, path, entry->kind, url,
                       cf_url ? entry->copyfrom_rev : entry->revision, 
                       cf_url, state_flags);
    }

  /* For directories, recursively handle each of their entries (except
     when the directory is being deleted, unless the deletion is part
     of a replacement ... how confusing). */
  if ((entries) 
      && ((! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
          || (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)))
    {
      apr_hash_index_t *hi;
      svn_wc_entry_t *this_entry;
      svn_stringbuf_t *full_path = svn_stringbuf_dup (path, subpool);
      svn_stringbuf_t *this_url = svn_stringbuf_dup (url, subpool);
      svn_stringbuf_t *this_cf_url
        = cf_url ? svn_stringbuf_dup (cf_url, subpool) : NULL;

      /* Loop over all other entries in this directory, skipping the
         "this dir" entry. */
      for (hi = apr_hash_first (subpool, entries); hi; hi = apr_hash_next (hi))
        {
          const void *key;
          apr_ssize_t klen;
          void *val;
          const char *name;
          svn_stringbuf_t *used_url = NULL;

          /* Get the next entry */
          apr_hash_this (hi, &key, &klen, &val);
          name = (const char *) key;
          
          /* Skip "this dir" */
          if (! strcmp (name, SVN_WC_ENTRY_THIS_DIR))
            continue;

          /* Name is an entry name; value is an entry structure. */
          this_entry = (svn_wc_entry_t *) val;
          svn_path_add_component_nts (full_path, name);
          if (this_cf_url)
            svn_path_add_component_nts (this_cf_url, name);

          /* We'll use the entry's URL if it has one and if we aren't
             in copy_mode, else, we'll just extend the parent's URL
             with the entry's basename.  */
          if ((! this_entry->url) || (copy_mode))
            {
              svn_path_add_component_nts (this_url, name);
              used_url = this_url;
            }

          /* Recurse. */
          SVN_ERR (harvest_committables 
                   (committables, locked_dirs, full_path,
                    used_url ? used_url : this_entry->url,
                    this_cf_url,
                    (svn_wc_entry_t *)val, 
                    adds_only,
                    copy_mode,
                    subpool));

          /* Truncate paths back to their pre-loop state. */
          svn_stringbuf_chop (full_path, klen + 1);
          if (this_cf_url)
            svn_stringbuf_chop (this_cf_url, klen + 1);
          if (used_url)
            svn_stringbuf_chop (this_url, klen + 1);
        }
    }

  /* Destroy the subpool. */
  svn_pool_destroy (subpool);

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__harvest_committables (apr_hash_t **committables,
                                  apr_hash_t **locked_dirs,
                                  svn_stringbuf_t *parent_dir,
                                  apr_array_header_t *targets,
                                  apr_pool_t *pool)
{
  int i = 0;
  svn_stringbuf_t *target = svn_stringbuf_dup (parent_dir, pool);
  
  /* Create the COMMITTABLES hash. */
  *committables = apr_hash_make (pool);

  /* Create the LOCKED_DIRS hash. */
  *locked_dirs = apr_hash_make (pool);

  do
    {
      svn_wc_entry_t *entry;
      svn_stringbuf_t *url;

      /* Add the relative portion of our full path (if there are no
         relative paths, TARGET will just be PARENT_DIR for a single
         iteration. */
      if (targets->nelts)
        svn_path_add_component (target, 
                                (((svn_stringbuf_t **) targets->elts)[i]));

      /* No entry?  This TARGET isn't even under version control! */
      SVN_ERR (svn_wc_entry (&entry, target, pool));
      if (! entry)
        return svn_error_create 
          (SVN_ERR_ENTRY_NOT_FOUND, 0, NULL, pool, target->data);
      
      if (! entry->url)
        {
          svn_stringbuf_t *parent, *basename;
          svn_wc_entry_t *p_entry;
          svn_boolean_t wc_root;

          /* An entry with no URL should only come about when it is
             scheduled for addition or replacement. */
          if (! ((entry->schedule == svn_wc_schedule_add)
                 || (entry->schedule == svn_wc_schedule_replace)))
            return svn_error_createf 
              (SVN_ERR_WC_CORRUPT, 0, NULL, pool, 
               "Entry for `%s' has no URL, yet is not scheduled for addition",
               target->data);

          /* Check for WC-root-ness. */
          SVN_ERR (svn_wc_is_wc_root (&wc_root, target, pool));
          if (wc_root)
            return svn_error_createf 
              (SVN_ERR_ILLEGAL_TARGET, 0, NULL, pool, 
               "Entry for `%s' has no URL, and none can be derived for it",
               target->data);
          
          /* See if the parent is under version control (corruption if it
             isn't) and possibly scheduled for addition (illegal target if
             it is). */
          svn_path_split (target, &parent, &basename, pool);
          if (svn_path_is_empty (parent))
            parent = svn_stringbuf_create (".", pool);
          SVN_ERR (svn_wc_entry (&p_entry, parent, pool));
          if (! p_entry)
            return svn_error_createf 
              (SVN_ERR_WC_CORRUPT, 0, NULL, pool, 
               "Entry for `%s' has no URL, and its parent directory does"
               "not appear to be under version control", target->data);
          if ((p_entry->schedule == svn_wc_schedule_add)
              || (p_entry->schedule == svn_wc_schedule_replace))
            return svn_error_createf 
              (SVN_ERR_ILLEGAL_TARGET, 0, NULL, pool, 
               "`%s' is the child an unversioned (or not-yet-versioned)"
               "directory.  Try committing the directory itself",
               target->data);
          
          /* Manufacture a URL for this TARGET. */
          url = svn_stringbuf_dup (p_entry->url, pool);
          svn_path_add_component (url, basename);
        }
      else
        url = entry->url;
      
      /* If this entry is marked as 'copied' but scheduled normally, then
         it should be the child of something else marked for addition with
         history. */
      if ((entry->copied) && (entry->schedule == svn_wc_schedule_normal))
        return svn_error_createf 
          (SVN_ERR_ILLEGAL_TARGET, 0, NULL, pool, 
           "Entry for `%s' is marked as `copied' but is not itself scheduled "
           "for addition.  Perhaps you're committing a target that this "
           "inside of an unversioned (or not-yet-versioned) directory?",
           target->data);

      /* Handle our TARGET. */
      SVN_ERR (harvest_committables (*committables, *locked_dirs, target, 
                                     url, NULL, entry, FALSE, FALSE, pool));

      /* Reset our base path for the next iteration, and increment our
         counter. */
      svn_stringbuf_chop (target, target->len - parent_dir->len);
      i++;
    }
  while (i < targets->nelts);

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__get_copy_committables (apr_hash_t **committables,
                                   apr_hash_t **locked_dirs,
                                   svn_stringbuf_t *new_url,
                                   svn_stringbuf_t *target,
                                   apr_pool_t *pool)
{
  svn_wc_entry_t *entry;

  /* Create the COMMITTABLES hash. */
  *committables = apr_hash_make (pool);

  /* Create the LOCKED_DIRS hash. */
  *locked_dirs = apr_hash_make (pool);

  /* Read the entry for TARGET. */
  SVN_ERR (svn_wc_entry (&entry, target, pool));
  if (! entry)
    return svn_error_create 
      (SVN_ERR_ENTRY_NOT_FOUND, 0, NULL, pool, target->data);
      
  /* Handle our TARGET. */
  SVN_ERR (harvest_committables (*committables, *locked_dirs, target, 
                                 new_url, entry->url, entry, 
                                 FALSE, TRUE, pool));

  return SVN_NO_ERROR;
}


int svn_client__sort_commit_item_urls (const void *a, const void *b)
{
  svn_client_commit_item_t *item1 = *((svn_client_commit_item_t **) a);
  svn_client_commit_item_t *item2 = *((svn_client_commit_item_t **) b);
  return svn_path_compare_paths (item1->url, item2->url);
}



svn_error_t *
svn_client__condense_commit_items (svn_stringbuf_t **base_url,
                                   apr_array_header_t *commit_items,
                                   apr_pool_t *pool)
{
  apr_array_header_t *ci = commit_items; /* convenience */
  svn_stringbuf_t *url;
  svn_client_commit_item_t *item, *last_item = NULL;
  int i;
  
  assert (ci && ci->nelts);

  /* Sort our commit items by their URLs. */
  qsort (ci->elts, ci->nelts, 
         ci->elt_size, svn_client__sort_commit_item_urls);

  /* Loop through the URLs, finding the longest usable ancestor common
     to all of them, and making sure there are no duplicate URLs.  */
  for (i = 0; i < ci->nelts; i++)
    {
      item = (((svn_client_commit_item_t **) ci->elts)[i]);
      url = item->url;

      if ((last_item) && (svn_stringbuf_compare (last_item->url, url)))
        return svn_error_createf 
          (SVN_ERR_CLIENT_DUPLICATE_COMMIT_URL, 0, NULL, pool,
           "Cannot commit both `%s' and `%s' as they refer to the same URL.",
           item->path->data, last_item->path->data);

      /* In the first iteration, our BASE_URL is just are only
         encountered commit URL to date.  After that, we find the
         longest ancestor between the current BASE_URL and the current
         commit URL.  */
      if (i == 0)
        *base_url = svn_stringbuf_dup (url, pool);
      else
        *base_url = svn_path_get_longest_ancestor (*base_url, url, pool); 

      /* If our BASE_URL is itself a to-be-committed item, and it is
         anything other than an already-versioned directory with
         property mods, we'll call its parent directory URL the
         BASE_URL.  Why?  Because we can't have a file URL as our base
         -- period -- and all other directory operations (removal,
         addition, etc.) require that we open that directory's parent
         dir first.  */
      if (((*base_url)->len == url->len)
          && (! ((item->kind == svn_node_dir)
                 && item->state_flags == SVN_CLIENT_COMMIT_ITEM_PROP_MODS)))
        svn_path_remove_component (*base_url);

      /* Stash our item here for the next iteration. */
      last_item = item;
    }
  
  /* Now that we've settled on a *BASE_URL, go hack that base off
     of all of our URLs. */
  for (i = 0; i < ci->nelts; i++)
    {
      url = (((svn_client_commit_item_t **) ci->elts)[i])->url;
      if (url->len > (*base_url)->len)
        {
          memmove (url->data, 
                   url->data + (*base_url)->len + 1,
                   url->len - (*base_url)->len - 1);
          url->len = url->len - (*base_url)->len - 1;
          url->data[url->len] = 0;
        }
      else
        {
          url->data[0] = 0;
          url->len = 0;
        }
    }

#ifdef SVN_CLIENT_COMMIT_DEBUG
  /* ### TEMPORARY CODE ### */
  printf ("COMMITTABLES: (base url=%s)\n", (*base_url)->data);
  for (i = 0; i < ci->nelts; i++)
    {
      url = (((svn_client_commit_item_t **) ci->elts)[i])->url;
      printf ("   %s\n", url->data ? url->data : "");
    }  
#endif /* SVN_CLIENT_COMMIT_DEBUG */

  return SVN_NO_ERROR;
}


static svn_error_t *
init_stack (apr_array_header_t **db_stack,
            int *stack_ptr,
            const svn_delta_editor_t *editor,
            void *edit_baton,
            apr_pool_t *pool)
{
  void *db;

  /* Call the EDITOR's open_root function to get our first directory
     baton. */
  SVN_ERR (editor->open_root (edit_baton, SVN_INVALID_REVNUM, pool, &db));

  /* Now allocate an array for dir_batons and push our first one
     there, incrementing our stack pointer. */
  *db_stack = apr_array_make (pool, 4, sizeof (void *));
  (*((void **) apr_array_push (*db_stack))) = db;
  *stack_ptr = 1;

  return SVN_NO_ERROR;
}


static svn_error_t *
push_stack (const char *rel_url, /* relative to base url of commit */
            apr_array_header_t *db_stack,
            int *stack_ptr,
            const svn_delta_editor_t *editor,
            const char *copyfrom_path,
            svn_revnum_t revision,
            svn_boolean_t is_add,
            apr_pool_t *pool)
{
  void *parent_db, *db;
  
  assert (db_stack && db_stack->nelts && *stack_ptr);

  /* Call the EDITOR's open_directory function to get a new directory
     baton. */
  parent_db = ((void **) db_stack->elts)[*stack_ptr - 1];
  if (is_add)
    SVN_ERR (editor->add_directory (rel_url, parent_db, copyfrom_path,
                                    revision, pool, &db));
  else
    SVN_ERR (editor->open_directory (rel_url, parent_db, revision, pool, &db));

  /* If all our current stack space is in use, push the DB onto the
     end of the array (which will allocate more space).  Else, we will
     just re-use a previously allocated slot.  */
  if (*stack_ptr == db_stack->nelts)
    (*((void **) apr_array_push (db_stack))) = db;
  else
    ((void **) db_stack->elts)[*stack_ptr] = db;

  /* Increment our stack pointer and get outta here. */
  (*stack_ptr)++;
  return SVN_NO_ERROR;
}


static svn_error_t *
pop_stack (apr_array_header_t *db_stack,
           int *stack_ptr,
           const svn_delta_editor_t *editor)
{
  void *db;

  /* Decrement our stack pointer. */
  (*stack_ptr)--;

  /* Close the most recent directory pushed to the stack. */
  db = ((void **) db_stack->elts)[*stack_ptr];
  return editor->close_directory (db);
}


static int
count_components (const char *path)
{
  int count = 1;
  const char *instance = path;

  if ((strlen (path) == 1) && (path[0] == '/'))
    return 0;

  do
    {
      instance++;
      instance = strchr (instance, '/');
      if (instance)
        count++;
    }
  while (instance);

  return count;
}


struct file_mod_t
{
  svn_client_commit_item_t *item;
  void *file_baton;
};


static svn_error_t *
do_item_commit (const char *url,
                svn_client_commit_item_t *item,
                const svn_delta_editor_t *editor,
                apr_array_header_t *db_stack,
                int *stack_ptr,
                apr_array_header_t *file_mods,
                apr_hash_t *tempfiles,
                svn_wc_notify_func_t notify_func,
                void *notify_baton,
                svn_stringbuf_t *display_dir,
                apr_pool_t *pool)
{
  svn_node_kind_t kind = item->kind;
  void *file_baton = NULL, *parent_baton = NULL, *dir_baton = NULL;
  const char *copyfrom_url = item->copyfrom_url 
                             ? item->copyfrom_url->data
                             : NULL;

  /* Get the parent dir_baton. */
  parent_baton = ((void **) db_stack->elts)[*stack_ptr - 1];

  /* If a feedback table was supplied by the application layer,
     describe what we're about to do to this item.  */
  if (notify_func)
    {
      /* Convert an absolute path into a relative one (for feedback.) */
      const char *path = item->path->data + (display_dir->len + 1);

      if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
          && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
        (*notify_func) (notify_baton, svn_wc_notify_commit_replaced, path);

      else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
        (*notify_func) (notify_baton, svn_wc_notify_commit_deleted, path);

      else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
        (*notify_func) (notify_baton, svn_wc_notify_commit_added, path);

      else if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)
               || (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS))
        (*notify_func) (notify_baton, svn_wc_notify_commit_modified, path);
    }

  /* If this item is supposed to be deleted, do so. */
  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
    SVN_ERR (editor->delete_entry (url, item->revision, 
                                   parent_baton, pool));

  /* If this item is supposed to be added, do so. */
  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
    {
      if (kind == svn_node_file)
        {
          SVN_ERR (editor->add_file 
                   (url, parent_baton, copyfrom_url, 
                    item->revision,
                    pool, &file_baton));
        }
      else
        {
          SVN_ERR (push_stack 
                   (url, db_stack, stack_ptr, editor, copyfrom_url, 
                    item->revision,
                    TRUE, pool));
          dir_baton = ((void **) db_stack->elts)[*stack_ptr - 1];
        }
    }
    
  /* Now handle property mods. */
  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)
    {
      svn_stringbuf_t *tempfile;

      if (kind == svn_node_file)
        {
          if (! file_baton)
            SVN_ERR (editor->open_file (url, parent_baton, item->revision,
                                        pool, &file_baton));
        }
      else
        {
          if (! dir_baton)
            {
              SVN_ERR (push_stack (url, db_stack, stack_ptr, editor, NULL,
                                   item->revision, FALSE, pool));
              dir_baton = ((void **) db_stack->elts)[*stack_ptr - 1];
            }
        }

      SVN_ERR (svn_wc_transmit_prop_deltas 
               (item->path, kind, editor,
                (kind == svn_node_dir) ? dir_baton : file_baton, 
                &tempfile, pool));
      if (tempfile && tempfiles)
        apr_hash_set (tempfiles, tempfile->data, tempfile->len, (void *)1);
    }

  /* Finally, handle text mods (in that we need to open a file if it
     hasn't already been opened, and we need to put the file baton in
     our FILES hash). */
  if ((kind == svn_node_file) 
      && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS))
    {
      struct file_mod_t mod;

      if (! file_baton)
        SVN_ERR (editor->open_file (url, parent_baton,
                                    item->revision,
                                    pool, &file_baton));

      /* Copy in the contents of the mod structure to the array.  Note
         that this is NOT a copy of a pointer reference, but a copy of
         the structure's contents!! */
      mod.item = item;
      mod.file_baton = file_baton;
      (*((struct file_mod_t *) apr_array_push (file_mods))) = mod;
    }

  /* Close any outstanding file batons that didn't get caught by the
     "has local mods" conditional above. */
  else if (file_baton)
    SVN_ERR (editor->close_file (file_baton));
  
  return SVN_NO_ERROR;
}


#ifdef SVN_CLIENT_COMMIT_DEBUG
/* Prototype for function below */
static svn_error_t *get_test_editor (const svn_delta_editor_t **editor,
                                     void **edit_baton,
                                     const char *base_url,
                                     apr_pool_t *pool);
#endif /* SVN_CLIENT_COMMIT_DEBUG */

svn_error_t *
svn_client__do_commit (svn_stringbuf_t *base_url,
                       apr_array_header_t *commit_items,
                       const svn_delta_editor_t *editor,
                       void *edit_baton,
                       svn_wc_notify_func_t notify_func,
                       void *notify_baton,
                       svn_stringbuf_t *display_dir,
                       apr_hash_t **tempfiles,
                       apr_pool_t *pool)
{
  apr_array_header_t *db_stack;
  apr_array_header_t *file_mods 
    = apr_array_make (pool, 1, sizeof (struct file_mod_t));
  int i, stack_ptr = 0;

#ifdef SVN_CLIENT_COMMIT_DEBUG
  {
    const svn_delta_editor_t *test_editor;
    void *test_edit_baton;
    SVN_ERR (get_test_editor (&test_editor, &test_edit_baton, 
                              base_url->data, pool));
    svn_delta_compose_editors (&editor, &edit_baton,
                               editor, edit_baton,
                               test_editor, test_edit_baton, pool);
  }
#endif /* SVN_CLIENT_COMMIT_DEBUG */

  /* If the caller wants us to track temporary file creation, create a
     hash to store those paths in. */
  if (tempfiles)
    *tempfiles = apr_hash_make (pool);

  /* We start by opening the root. */
  SVN_ERR (init_stack (&db_stack, &stack_ptr, editor, edit_baton, pool));

  /* Now, loop over the commit items, traversing the URL tree and
     driving the editor. */
  for (i = 0; i < commit_items->nelts; i++)
    {
      svn_stringbuf_t *last_url, *item_url, *item_dir, *item_name;
      svn_stringbuf_t *common = NULL;
      svn_client_commit_item_t *item
        = ((svn_client_commit_item_t **) commit_items->elts)[i];
      
      /* Get the next commit item URL. */
      item_url = item->url;

      /*** Step A - Find the common ancestor of the last commit item
           and the current one.  For the first iteration, this is just
           the empty string.  ***/
      if (i > 0)
        common = svn_path_get_longest_ancestor (last_url, item_url, pool);
      if (! common)
        common = svn_stringbuf_create ("", pool);

      /*** Step B - Close any directories between the last commit item
           and the new common ancestor, if any need to be closed.
           Sometimes there is nothing to do here (like, for the first
           iteration, or when the last commit item was an ancestor of
           the current item).  ***/
      if ((i > 0) && (last_url->len > common->len))
        {
          char *rel = last_url->data + (common->len ? (common->len + 1) : 0);
          int count = count_components (rel);
          while (count--)
            {
              SVN_ERR (pop_stack (db_stack, &stack_ptr, editor));
            }
        }

      /*** Step C - Open any directories between the common ancestor
           and the parent of the commit item. ***/
      svn_path_split (item_url, &item_dir, &item_name, pool);
      if (item_dir->len > common->len)
        {
          char *rel = apr_pstrdup (pool, item_dir->data);
          char *piece = rel + common->len + 1;

          while (1)
            {
              /* Find the first separator. */
              piece = strchr (piece, '/');

              /* Temporarily replace it with a NULL terminator. */
              if (piece)
                *piece = 0;

              /* Open the subdirectory. */
              SVN_ERR (push_stack (rel, db_stack, &stack_ptr, 
                                   editor, NULL, SVN_INVALID_REVNUM,
                                   FALSE, pool));
              
              /* If we temporarily replaced a '/' with a NULL,
                 un-replace it and move our piece pointer to the
                 character after the '/' we found.  If there was no
                 piece found, though, we're done.  */
              if (piece)
                {
                  *piece = '/';
                  piece++;    
                }
              else
                break;
            }
        }

      /*** Step D - Commit the item.  ***/
      SVN_ERR (do_item_commit (item_url->data, item, editor,
                               db_stack, &stack_ptr, file_mods, *tempfiles,
                               notify_func, notify_baton, display_dir, pool));

      /* Save our state for the next iteration. */
      if ((item->kind == svn_node_dir)
          && ((! (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
              || (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)))
        last_url = item_url;
      else
        last_url = item_dir;
    }

  /* Close down any remaining open directory batons. */
  while (stack_ptr)
    {
      SVN_ERR (pop_stack (db_stack, &stack_ptr, editor));
    }

  /* Transmit outstanding text deltas. */
  for (i = 0; i < file_mods->nelts; i++)
    {
      struct file_mod_t *mod
        = ((struct file_mod_t *) file_mods->elts) + i;
      svn_client_commit_item_t *item = mod->item;
      void *file_baton = mod->file_baton;
      svn_stringbuf_t *tempfile;
      svn_boolean_t fulltext = FALSE;

      if (notify_func)
        (*notify_func) (notify_baton, svn_wc_notify_commit_postfix_txdelta, 
                        item->path->data);

      if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
        fulltext = TRUE;

      SVN_ERR (svn_wc_transmit_text_deltas (item->path, fulltext,
                                            editor, file_baton, 
                                            &tempfile, pool));
      if (tempfile && *tempfiles)
        apr_hash_set (*tempfiles, tempfile->data, tempfile->len, (void *)1);
    }

  /* Close the edit. */
  SVN_ERR (editor->close_edit (edit_baton));
  return SVN_NO_ERROR;
}


svn_client_commit_info_t *
svn_client__make_commit_info (svn_revnum_t revision,
                              const char *author,
                              const char *date,
                              apr_pool_t *pool)
{
  svn_client_commit_info_t *info;

  if (date || author || SVN_IS_VALID_REVNUM (revision))
    {
      info = apr_palloc (pool, sizeof (*info));
      info->date = date ? apr_pstrdup (pool, date) : NULL;
      info->author = author ? apr_pstrdup (pool, author) : NULL;
      info->revision = revision;
      return info;
    }
  return NULL;
}


#ifdef SVN_CLIENT_COMMIT_DEBUG

/*** Temporary test editor ***/

struct edit_baton
{
  const char *path;
};


static void *
make_baton (const char *path, apr_pool_t *pool)
{
  struct edit_baton *new_baton 
    = apr_pcalloc (pool, sizeof (struct edit_baton *));
  new_baton->path = apr_pstrdup (pool, path);
  return ((void *) new_baton);
}


static svn_error_t *
open_root (void *edit_baton,
           svn_revnum_t base_revision,
           apr_pool_t *dir_pool,
           void **root_baton)
{
  struct edit_baton *eb = edit_baton;
  printf ("TEST EDIT STARTED (base url=%s)\n", eb->path);
  *root_baton = make_baton (eb->path, dir_pool);
  return SVN_NO_ERROR;
}

static svn_error_t *
add_item (const char *path,
          void *parent_baton,
          const char *copyfrom_path,
          svn_revnum_t copyfrom_revision,
          apr_pool_t *pool,
          void **baton)
{
  printf ("   Adding  : %s\n", path);
  *baton = make_baton (path, pool);
  return SVN_NO_ERROR;
}

static svn_error_t *
delete_entry (const char *path,
              svn_revnum_t revision,
              void *parent_baton,
              apr_pool_t *pool)
{
  printf ("   Deleting: %s\n", path);
  return SVN_NO_ERROR;
}

static svn_error_t *
open_item (const char *path,
           void *parent_baton,
           svn_revnum_t base_revision,
           apr_pool_t *pool,
           void **baton)
{
  printf ("   Opening : %s\n", path);
  *baton = make_baton (path, pool);
  return SVN_NO_ERROR;
}

static svn_error_t *
close_item (void *baton)
{
  struct edit_baton *this = baton;
  printf ("   Closing : %s\n", this->path);
  return SVN_NO_ERROR;
}


static svn_error_t *
change_prop (void *file_baton,
             const char *name,
             const svn_string_t *value,
             apr_pool_t *pool)
{
  printf ("      PropSet (%s=%s)\n", name, value ? value->data : "");
  return SVN_NO_ERROR;
}

static svn_error_t *
apply_textdelta (void *file_baton,
                 svn_txdelta_window_handler_t *handler,
                 void **handler_baton)
{
  printf ("      Transmitting text...\n");
  *handler = *handler_baton = NULL;
  return SVN_NO_ERROR;
}

static svn_error_t *
close_edit (void *edit_baton)
{
  printf ("TEST EDIT COMPLETED\n");
  return SVN_NO_ERROR;
}

static svn_error_t *
get_test_editor (const svn_delta_editor_t **editor,
                 void **edit_baton,
                 const char *base_url,
                 apr_pool_t *pool)
{
  svn_delta_editor_t *ed = svn_delta_default_editor (pool);
  struct edit_baton *eb = apr_pcalloc (pool, sizeof (*eb));

  eb->path = apr_pstrdup (pool, base_url);

  ed->open_root = open_root;
  ed->add_directory = add_item;
  ed->open_directory = open_item;
  ed->close_directory = close_item;
  ed->add_file = add_item;
  ed->open_file = open_item;
  ed->close_file = close_item;
  ed->delete_entry = delete_entry;
  ed->apply_textdelta = apply_textdelta;
  ed->change_dir_prop = change_prop;
  ed->change_file_prop = change_prop;
  ed->close_edit = close_edit;

  *editor = ed;
  *edit_baton = eb;
  return SVN_NO_ERROR;
}
#endif /* SVN_CLIENT_COMMIT_DEBUG */
  

/* 
 * local variables:
 * eval: (load-file "../../tools/dev/svn-dev.el")
 * end: */

