/*
 * delta.c:   an editor driver for svn_repos_dir_delta
 *
 * ====================================================================
 * 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 "svn_types.h"
#include "svn_delta.h"
#include "svn_fs.h"
#include "svn_path.h"
#include "apr_hash.h"
#include "svn_repos.h"
#include "svn_pools.h"



/* THINGS TODO:  Currently the code herein gives only a slight nod to
   fully supporting directory deltas that involve renames, copies, and
   such.  */
 

/* Some datatypes and declarations used throughout the file.  */


/* Parameters which remain constant throughout a delta traversal.
   At the top of the recursion, we initialize one of these structures.
   Then, we pass it down, unchanged, to every call.  This way,
   functions invoked deep in the recursion can get access to this
   traversal's global parameters, without using global variables.  */
struct context {
  const svn_delta_edit_fns_t *editor;
  svn_fs_root_t *source_root;
  apr_hash_t *source_rev_diffs;
  svn_fs_root_t *target_root;
  svn_boolean_t text_deltas;
  svn_boolean_t recurse;
  svn_boolean_t use_copyfrom_args;
  int target_is_rev;
};


/* The type of a function that accepts changes to an object's property
   list.  OBJECT is the object whose properties are being changed.
   NAME is the name of the property to change.  VALUE is the new value
   for the property, or zero if the property should be deleted.  */
typedef svn_error_t *proplist_change_fn_t (struct context *c,
                                           void *object,
                                           const char *name,
                                           const svn_string_t *value,
                                           apr_pool_t *pool);



/* Some prototypes for functions used throughout.  See each individual
   function for information about what it does.  */


/* Retrieving the base revision from the path/revision hash.  */
static svn_revnum_t get_revision_from_hash (apr_hash_t *hash, 
                                            const char *path,
                                            apr_pool_t *pool);


/* proplist_change_fn_t property changing functions.  */
static svn_error_t *change_dir_prop (struct context *c, 
                                     void *object,
                                     const char *name, 
                                     const svn_string_t *value,
                                     apr_pool_t *pool);

static svn_error_t *change_file_prop (struct context *c, 
                                      void *object,
                                      const char *name, 
                                      const svn_string_t *value,
                                      apr_pool_t *pool);


/* Constructing deltas for properties of files and directories.  */
static svn_error_t *delta_proplists (struct context *c,
                                     const char *source_path,
                                     const char *target_path,
                                     proplist_change_fn_t *change_fn,
                                     void *object,
                                     apr_pool_t *pool);


/* Constructing deltas for file constents.  */
static svn_error_t *send_text_delta (struct context *c,
                                     void *file_baton,
                                     svn_txdelta_stream_t *delta_stream,
                                     apr_pool_t *pool);

static svn_error_t *delta_files (struct context *c, 
                                 void *file_baton,
                                 const char *source_path,
                                 const char *target_path,
                                 apr_pool_t *pool);


/* Generic directory deltafication routines.  */
static svn_error_t *delete (struct context *c, 
                            void *dir_baton, 
                            const char *target_entry,
                            apr_pool_t *pool);

static svn_error_t *add_file_or_dir (struct context *c, 
                                     void *dir_baton, 
                                     const char *source_parent, 
                                     const char *source_entry,
                                     const char *target_parent, 
                                     const char *target_entry,
                                     apr_pool_t *pool);

static svn_error_t *replace_file_or_dir (struct context *c, 
                                         void *dir_baton,
                                         const char *source_parent, 
                                         const char *source_entry,
                                         const char *target_parent,
                                         const char *target_entry,
                                         apr_pool_t *pool);

static svn_error_t *find_nearest_entry (svn_fs_dirent_t **s_entry,
                                        int *distance,
                                        struct context *c, 
                                        const char *source_parent, 
                                        const char *target_parent,
                                        const svn_fs_dirent_t *t_entry,
                                        apr_pool_t *pool);

static svn_error_t *delta_dirs (struct context *c, 
                                void *dir_baton,
                                const char *source_path, 
                                const char *target_path,
                                apr_pool_t *pool);



static svn_error_t *
not_a_dir_error (const char *role, 
                 const char *path,
                 apr_pool_t *pool)
{
  return svn_error_createf 
    (SVN_ERR_FS_NOT_DIRECTORY, 0, 0, pool,
     "not_a_dir_error: invalid %s directory '%s'",
     role, path ? path : "(null)");
}


/* Public interface to computing directory deltas.  */
svn_error_t *
svn_repos_dir_delta (svn_fs_root_t *src_root,
                     const char *src_parent_dir,
                     const char *src_entry,
                     apr_hash_t *src_revs,
                     svn_fs_root_t *tgt_root,
                     const char *tgt_path,
                     const svn_delta_edit_fns_t *editor,
                     void *edit_baton,
                     svn_boolean_t text_deltas,
                     svn_boolean_t recurse,
                     svn_boolean_t use_copyfrom_args,
                     apr_pool_t *pool)
{
  void *root_baton;
  struct context c;
  svn_stringbuf_t *tgt_parent_dir, *tgt_entry;
  svn_stringbuf_t *src_fullpath;
  svn_fs_id_t *src_id, *tgt_id;
  svn_error_t *err;
  int distance;

  /* ### need to change svn_path_is_empty() */
  svn_stringbuf_t *tempbuf;

  /* SRC_PARENT_DIR must be valid. */
  if (! src_parent_dir)
    return not_a_dir_error ("source parent", src_parent_dir, pool);

  /* TGT_PATH must be valid. */
  if (! tgt_path)
    return svn_error_create (SVN_ERR_FS_PATH_SYNTAX, 0, 0, pool,
                             "svn_repos_dir_delta: invalid target path");

  tempbuf = svn_stringbuf_create (tgt_path, pool);

  /* Aplit TGT_PATH into TGT_PARENT_DIR and TGT_ENTRY unless SRC_ENTRY
     is NULL or TGT_PATH cannot be split. */
  if ((! src_entry) || (svn_path_is_empty (tempbuf)))
    {
      tgt_parent_dir = svn_stringbuf_create (tgt_path, pool);
      tgt_entry = NULL;
    }
  else
    {
      svn_path_split (tempbuf, &tgt_parent_dir, &tgt_entry, pool);
    }

  /* Make sure that parent dirs are really directories under both the
     source and target roots.  This also doubles as an existence
     check.  Obviously, an empty parent path is the root of the
     repository, guaranteed to exist as a directory. */
  svn_stringbuf_set (tempbuf, src_parent_dir);
  if (! svn_path_is_empty (tempbuf))
    {
      int s_dir, t_dir;
      SVN_ERR (svn_fs_is_dir (&s_dir, src_root, src_parent_dir, pool));
      SVN_ERR (svn_fs_is_dir (&t_dir, tgt_root, tgt_parent_dir->data, pool));
      if ((! s_dir) || (! t_dir))
        return not_a_dir_error ("source parent", src_parent_dir, pool);
    }
  if (! svn_path_is_empty (tgt_parent_dir))
    {
      int s_dir, t_dir;
      SVN_ERR (svn_fs_is_dir (&s_dir, src_root, tgt_parent_dir->data, pool));
      SVN_ERR (svn_fs_is_dir (&t_dir, tgt_root, tgt_parent_dir->data, pool));
      if ((! s_dir) || (! t_dir))
        return not_a_dir_error ("target parent", tgt_parent_dir->data, pool);
    }
  
  /* Setup our pseudo-global structure here.  We need these variables
     throughout the deltafication process, so pass them around by
     reference to all the helper functions. */
  c.editor = editor;
  c.source_root = src_root;
  c.source_rev_diffs = src_revs;
  c.target_root = tgt_root;
  c.target_is_rev = svn_fs_is_revision_root (tgt_root);
  c.recurse = recurse;
  c.text_deltas = text_deltas;

#if SVN_REPOS_SUPPORT_COPY_FROM_ARGS
  c.use_copyfrom_args = use_copyfrom_args;
#else
  c.use_copyfrom_args = FALSE;
#endif

  /* Set the global target revision if the target is a revision. */
  if (c.target_is_rev)
    SVN_ERR (editor->set_target_revision 
             (edit_baton, svn_fs_revision_root_revision (tgt_root)));

  /* Call open_root to get our root_baton... */
  SVN_ERR (editor->open_root 
           (edit_baton, 
            get_revision_from_hash (src_revs, src_parent_dir, pool),
            &root_baton));

  /* Construct the full path of the source and target update items. */
  src_fullpath = svn_stringbuf_create (src_parent_dir, pool);
  if (src_entry && *src_entry != '\0')
    svn_path_add_component_nts (src_fullpath, src_entry);

  /* Get the node ids for the source and target paths. */
  err = svn_fs_node_id (&tgt_id, tgt_root, tgt_path, pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
        {
          /* Caller thinks that target still exists, but it doesn't.
             So just delete the target and go home.  */
          svn_error_clear_all (err);
          SVN_ERR (delete (&c, root_baton, src_entry, pool));
          goto cleanup;
        }
      else
        {
          return err;
        }
    }
  err = svn_fs_node_id (&src_id, src_root, src_fullpath->data, pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
        {
          /* The target has been deleted from our working copy. Add
             back a new one. */
          svn_error_clear_all (err);
          SVN_ERR (add_file_or_dir (&c, root_baton,
                                    NULL,
                                    NULL,
                                    tgt_parent_dir->data,
                                    tgt_entry->data,
                                    pool));
        }
      else
        {
          return err;
        }
    }
  else if (src_entry && *src_entry != '\0')
    {
      /* Use the distance between the node ids to determine the best
         way to update the requested entry. */
      distance = svn_fs_id_distance (src_id, tgt_id);
      if (distance == 0)
        {
          /* They're the same node!  No-op (you gotta love those). */
        }
      else if (distance == -1)
        {
          /* The nodes are not related at all.  Delete the one, and
             add the other. */
          SVN_ERR (delete (&c, root_baton, src_entry, pool));
          SVN_ERR (add_file_or_dir (&c, root_baton,
                                    NULL, NULL,
                                    tgt_parent_dir->data,
                                    tgt_entry->data,
                                    pool));
        }
      else
        {
          /* The nodes are at least related.  Just open the one
             with the other. */
          SVN_ERR (replace_file_or_dir (&c, root_baton,
                                        src_parent_dir,
                                        src_entry,
                                        tgt_parent_dir->data,
                                        tgt_entry->data,
                                        pool));
        }
    }
  else
    {
      /* There is no entry given, so update the whole parent directory. */
      SVN_ERR (delta_dirs (&c, root_baton,
                           src_fullpath->data, tgt_path,
                           pool));
    }

 cleanup:

  /* Make sure we close the root directory we opened above. */
  SVN_ERR (editor->close_directory (root_baton));

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

  /* All's well that ends well. */
  return SVN_NO_ERROR;
}



/* Retrieving the base revision from the path/revision hash.  */


/* Look through a HASH (with paths as keys, and pointers to revision
   numbers as values) for the revision associated with the given PATH.
   Perform all necessary memory allocations in POOL.  */
static svn_revnum_t
get_revision_from_hash (apr_hash_t *hash, const char *path,
                        apr_pool_t *pool)
{
  void *val;
  svn_stringbuf_t *path_copy;
  svn_revnum_t revision = SVN_INVALID_REVNUM;

  if (! hash)
    return SVN_INVALID_REVNUM;

  /* See if this path has a revision assigned in the hash. */
  val = apr_hash_get (hash, path, APR_HASH_KEY_STRING);
  if (val)
    {
      revision = *((svn_revnum_t *) val);
      if (SVN_IS_VALID_REVNUM(revision))
        return revision;      
    }

  /* Make a copy of our path that we can hack on. */
  path_copy = svn_stringbuf_create (path, pool);

  /* If we haven't found a valid revision yet, and our copy of the
     path isn't empty, hack the last component off the path and see if
     *that* has a revision entry in our hash. */
  while ((! SVN_IS_VALID_REVNUM(revision)) 
         && (! svn_path_is_empty (path_copy)))
    {
      svn_path_remove_component (path_copy);

      val = apr_hash_get (hash, path_copy->data, APR_HASH_KEY_STRING);
      if (val)
        revision = *((svn_revnum_t *) val);
    }
  
  return revision;
}




/* proplist_change_fn_t property changing functions.  */


/* Call the directory property-setting function of C->editor to set
   the property NAME to given VALUE on the OBJECT passed to this
   function. */
static svn_error_t *
change_dir_prop (struct context *c, void *object,
                 const char *name, const svn_string_t *value,
                 apr_pool_t *pool)
{
  /* ### fix editor interface */
  svn_stringbuf_t *namebuf = svn_stringbuf_create (name, pool);
  svn_stringbuf_t *valbuf =
    value ? svn_stringbuf_create_from_string (value, pool) : NULL;

  return c->editor->change_dir_prop (object, namebuf, valbuf);
}


/* Call the file property-setting function of C->editor to set the
   property NAME to given VALUE on the OBJECT passed to this
   function. */
static svn_error_t *
change_file_prop (struct context *c, void *object,
                  const char *name, const svn_string_t *value,
                  apr_pool_t *pool)
{
  /* ### fix editor interface */
  svn_stringbuf_t *namebuf = svn_stringbuf_create (name, pool);
  svn_stringbuf_t *valbuf =
    value ? svn_stringbuf_create_from_string (value, pool) : NULL;

  return c->editor->change_file_prop (object, namebuf, valbuf);
}




/* Constructing deltas for properties of files and directories.  */


/* Generate the appropriate property editing calls to turn the
   properties of SOURCE_PATH into those of TARGET_PATH.  If
   SOURCE_PATH is NULL, treat it as if it were a file with no
   properties.  Pass OBJECT on to the editor function wrapper
   CHANGE_FN. */
static svn_error_t *
delta_proplists (struct context *c,
                 const char *source_path,
                 const char *target_path,
                 proplist_change_fn_t *change_fn,
                 void *object,
                 apr_pool_t *pool)
{
  apr_hash_t *s_props = 0;
  apr_hash_t *t_props = 0;
  apr_hash_index_t *hi;
  apr_pool_t *subpool;

  /* Make a subpool for local allocations. */ 
  subpool = svn_pool_create (pool);

  if (source_path && target_path)
    {
      int changed;

      /* Is this deltification worth our time? */
      SVN_ERR (svn_fs_props_changed (&changed,
                                     c->target_root,
                                     target_path,
                                     c->source_root,
                                     source_path,
                                     subpool));
      if (! changed)
        {
          svn_pool_destroy (subpool);
          return SVN_NO_ERROR;
        }
    }

  /* Get the source file's properties */
  if (source_path)
    SVN_ERR (svn_fs_node_proplist 
             (&s_props, c->source_root, source_path,
              subpool));

  /* Get the target file's properties */
  if (target_path)
    SVN_ERR (svn_fs_node_proplist 
             (&t_props, c->target_root, target_path,
              subpool));

  for (hi = apr_hash_first (subpool, t_props); hi; hi = apr_hash_next (hi))
    {
      const svn_string_t *s_value;
      const void *key;
      void *val;
      apr_ssize_t klen;
          
      /* KEY is property name in target, VAL the value */
      apr_hash_this (hi, &key, &klen, &val);

      /* See if this property existed in the source.  If so, and if
         the values in source and target differ, open the value in
         target with the one in source. */
      if (s_props 
          && ((s_value = apr_hash_get (s_props, key, klen)) != 0))
        {
          if (! svn_string_compare (s_value, val))
            SVN_ERR (change_fn (c, object, key, val, subpool));

          /* Remove the property from source list so we can track
             which items have matches in the target list. */
          apr_hash_set (s_props, key, klen, NULL);
        }
      else
        {
          /* This property didn't exist in the source, so this is just
             an add. */
          SVN_ERR (change_fn (c, object, key, val, subpool));
        }
    }

  /* All the properties remaining in the source list are not present
     in the target, and so must be deleted. */
  if (s_props)
    {
      for (hi = apr_hash_first (subpool, s_props); hi; hi = apr_hash_next (hi))
        {
          const void *key;
          
          /* KEY is property name in target, VAL the value */
          apr_hash_this (hi, &key, NULL, NULL);

          SVN_ERR (change_fn (c, object, key, NULL, subpool));
        }
    }

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

  return SVN_NO_ERROR;
}




/* Constructing deltas for file constents.  */


/* Change the contents of FILE_BATON in C->editor, according to the
   text delta from DELTA_STREAM.  */
static svn_error_t *
send_text_delta (struct context *c,
                 void *file_baton,
                 svn_txdelta_stream_t *delta_stream,
                 apr_pool_t *pool)
{
  svn_txdelta_window_handler_t delta_handler;
  void *delta_handler_baton;

  /* Get a handler that will apply the delta to the file.  */
  SVN_ERR (c->editor->apply_textdelta 
           (file_baton, &delta_handler, &delta_handler_baton));

  
  if (c->text_deltas)
    {
      /* Deliver the delta stream to the file.  */
      SVN_ERR (svn_txdelta_send_txstream (delta_stream,
                                          delta_handler,
                                          delta_handler_baton,
                                          pool));
    }
  else
    {
      /* The caller doesn't want text delta data.  Just send a single
         NULL window. */
      SVN_ERR (delta_handler (NULL, delta_handler_baton));
    }

  return SVN_NO_ERROR;
}


/* Make the appropriate edits on FILE_BATON to change its contents and
   properties from those in SOURCE_PATH to those in TARGET_PATH. */
static svn_error_t *
delta_files (struct context *c, void *file_baton,
             const char *source_path,
             const char *target_path,
             apr_pool_t *pool)
{
  svn_txdelta_stream_t *delta_stream;
  apr_pool_t *subpool;

  /* Make a subpool for local allocations. */
  subpool = svn_pool_create (pool);

  /* Compare the files' property lists.  */
  SVN_ERR (delta_proplists (c, source_path, target_path,
                            change_file_prop, file_baton, subpool));

  /* ### this is too much work if !c->text_deltas. there is no reason to
     ### ask the FS for a delta stream if we aren't going to use it. */

  if (source_path)
    {
      int changed;

      /* Is this deltification worth our time? */
      SVN_ERR (svn_fs_contents_changed (&changed,
                                        c->target_root,
                                        target_path,
                                        c->source_root,
                                        source_path,
                                        subpool));
      if (! changed)
        {
          svn_pool_destroy (subpool);
          return SVN_NO_ERROR;
        }

      /* Get a delta stream turning SOURCE_PATH's contents into
         TARGET_PATH's contents.  */
      SVN_ERR (svn_fs_get_file_delta_stream 
               (&delta_stream, 
                c->source_root, source_path,
                c->target_root, target_path,
                subpool));
    }
  else
    {
      /* Get a delta stream turning an empty file into one having
         TARGET_PATH's contents.  */
      SVN_ERR (svn_fs_get_file_delta_stream 
               (&delta_stream, 0, 0,
                c->target_root, target_path, subpool));
    }

  SVN_ERR (send_text_delta (c, file_baton, delta_stream, subpool));

  /* Cleanup. */
  svn_pool_destroy (subpool);

  return 0;
}




/* Generic directory deltafication routines.  */


/* Emit a delta to delete the entry named TARGET_ENTRY from DIR_BATON.  */
static svn_error_t *
delete (struct context *c, 
        void *dir_baton, 
        const char *target_entry,
        apr_pool_t *pool)
{
  /* ### change the editor prototypes... */
  svn_stringbuf_t *entrybuf = svn_stringbuf_create (target_entry, pool);

  return c->editor->delete_entry (entrybuf, SVN_INVALID_REVNUM, dir_baton);
}


/* Emit a delta to create the entry named TARGET_ENTRY in the
   directory TARGET_PARENT.  If SOURCE_PARENT and SOURCE_ENTRY are
   valid, use them to determine the copyfrom args in the editor's add
   calls.  Pass DIR_BATON through to editor functions that require it.  */
static svn_error_t *
add_file_or_dir (struct context *c, void *dir_baton,
                 const char *source_parent,
                 const char *source_entry,
                 const char *target_parent,
                 const char *target_entry,
                 apr_pool_t *pool)
{
  int is_dir;
  svn_stringbuf_t *target_full_path;
  svn_stringbuf_t *source_full_path;
  svn_revnum_t base_revision = SVN_INVALID_REVNUM;

  /* ### change the delta interface */
  svn_stringbuf_t *namebuf;

  if (!target_parent || !target_entry)
    abort();

  /* Get the target's full path */
  target_full_path = svn_stringbuf_create (target_parent, pool);
  svn_path_add_component_nts (target_full_path, target_entry);

  /* Is the target a file or a directory?  */
  SVN_ERR (svn_fs_is_dir (&is_dir, c->target_root, 
                          target_full_path->data, pool));

  if (source_parent && source_entry)
    {
      /* Get the source's full path */
      source_full_path = svn_stringbuf_create (source_parent, pool);
      svn_path_add_component_nts (source_full_path, source_entry);

      /* Get the base revision for the entry from the hash. */
      base_revision = get_revision_from_hash (c->source_rev_diffs,
                                              source_full_path->data,
                                              pool);
    }
  else
    source_full_path = NULL;

  namebuf = svn_stringbuf_create (target_entry, pool);
  if (is_dir)
    {
      void *subdir_baton;

      SVN_ERR (c->editor->add_directory 
               (namebuf, dir_baton, 
                source_full_path, base_revision, &subdir_baton));
      SVN_ERR (delta_dirs (c, subdir_baton,
                           source_full_path ? source_full_path->data : NULL,
                           target_full_path->data, pool));
      SVN_ERR (c->editor->close_directory (subdir_baton));
    }
  else
    {
      void *file_baton;

      SVN_ERR (c->editor->add_file 
               (namebuf, dir_baton, 
                source_full_path, base_revision, &file_baton));
      SVN_ERR (delta_files (c, file_baton,
                            source_full_path ? source_full_path->data : NULL,
                            target_full_path->data, pool));
      SVN_ERR (c->editor->close_file (file_baton));
    }

  return SVN_NO_ERROR;
}


/* Modify the directory TARGET_PARENT by replacing its entry named
   TARGET_ENTRY with the SOURCE_ENTRY found in SOURCE_PARENT.  Pass
   DIR_BATON through to editor functions that require it. */
static svn_error_t *
replace_file_or_dir (struct context *c, 
                     void *dir_baton,
                     const char *target_parent, 
                     const char *target_entry,
                     const char *source_parent, 
                     const char *source_entry,
                     apr_pool_t *pool)
{
  int is_dir;
  svn_stringbuf_t *source_full_path = 0;
  svn_stringbuf_t *target_full_path = 0;
  svn_revnum_t base_revision = SVN_INVALID_REVNUM;

  /* ### change the delta interface */
  svn_stringbuf_t *namebuf;

  if (!target_parent || !target_entry)
    abort();

  if (!source_parent || !source_entry)
    abort();

  /* Get the target's full path */
  target_full_path = svn_stringbuf_create (target_parent, pool);
  svn_path_add_component_nts (target_full_path, target_entry);

  /* Is the target a file or a directory?  */
  SVN_ERR (svn_fs_is_dir (&is_dir, c->target_root, 
                          target_full_path->data, pool));

  /* Get the source's full path */
  source_full_path = svn_stringbuf_create (source_parent, pool);
  svn_path_add_component_nts (source_full_path, source_entry);

  /* Get the base revision for the entry from the hash. */
  base_revision = get_revision_from_hash (c->source_rev_diffs,
                                          source_full_path->data,
                                          pool);

  namebuf = svn_stringbuf_create (target_entry, pool);
  if (is_dir)
    {
      void *subdir_baton;

      SVN_ERR (c->editor->open_directory 
               (namebuf, dir_baton, base_revision, &subdir_baton));
      SVN_ERR (delta_dirs (c, subdir_baton,
                           source_full_path->data, target_full_path->data,
                           pool));
      SVN_ERR (c->editor->close_directory (subdir_baton));
    }
  else
    {
      void *file_baton;

      SVN_ERR (c->editor->open_file 
               (namebuf, dir_baton, base_revision, &file_baton));
      SVN_ERR (delta_files (c, file_baton,
                            source_full_path->data, target_full_path->data,
                            pool));
      SVN_ERR (c->editor->close_file (file_baton));
    }

  return SVN_NO_ERROR;
}


/* Do a `replace' edit in DIR_BATON, replacing the entry named
   T_ENTRY->name in the directory TARGET_PARENT with the closest
   related node available in SOURCE_PARENT.  If no relative can be
   found, simply delete in the entry from TARGET_PARENT, and then
   re-add the new one. */
static svn_error_t *
find_nearest_entry (svn_fs_dirent_t **s_entry,
                    int *distance,
                    struct context *c, 
                    const char *source_parent, 
                    const char *target_parent,
                    const svn_fs_dirent_t *t_entry,
                    apr_pool_t *pool)
{
  apr_hash_t *s_entries;
  apr_hash_index_t *hi;
  int best_distance = -1;
  svn_fs_dirent_t *best_entry = NULL;
  svn_stringbuf_t *source_full_path;
  svn_stringbuf_t *target_full_path;
  int t_is_dir;
  apr_pool_t *subpool;
  
  /* Make a subpool for local allocations */
  subpool = svn_pool_create (pool);

  /* If there's no source to search, return a failed ancestor hunt. */
  source_full_path = svn_stringbuf_create ("", subpool);
  if (! source_parent)
    {
      *s_entry = 0;
      *distance = -1;
      svn_pool_destroy (subpool);
      return SVN_NO_ERROR;
    }

  /* Get the list of entries in source.  Note that we are using the
     pool that was passed in instead of the subpool...we're returning
     a reference to an item in this hash, and it would suck to blow it
     away before our caller gets a chance to see it.  */
  SVN_ERR (svn_fs_dir_entries (&s_entries, c->source_root,
                               source_parent, pool));

  target_full_path = svn_stringbuf_create (target_parent, subpool);
  svn_path_add_component_nts (target_full_path, t_entry->name);

  /* Is the target a file or a directory?  */
  SVN_ERR (svn_fs_is_dir (&t_is_dir, c->target_root, 
                          target_full_path->data, subpool));

  /* Find the closest relative to TARGET_ENTRY in SOURCE.
     
     In principle, a replace operation can choose the ancestor from
     anywhere in the delta's whole source tree.  In this
     implementation, we only search SOURCE for possible ancestors.
     This will need to improve, so we can find the best ancestor, no
     matter where it's hidden away in the source tree.  */
  for (hi = apr_hash_first (subpool, s_entries); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      void *val;
      apr_ssize_t klen;
      int this_distance;
      svn_fs_dirent_t *this_entry;
      int s_is_dir;
     
      /* KEY will be the entry name in source, VAL the dirent */
      apr_hash_this (hi, &key, &klen, &val);
      this_entry = val;

      svn_stringbuf_set (source_full_path, source_parent);
      svn_path_add_component_nts (source_full_path, this_entry->name);

      /* Is this entry a file or a directory?  */
      SVN_ERR (svn_fs_is_dir (&s_is_dir, c->source_root, 
                              source_full_path->data, subpool));

      /* If we aren't looking at the same node type, skip this
         entry. */
      if ((s_is_dir && (! t_is_dir)) || ((! s_is_dir) && t_is_dir))
        continue;

      /* Find the distance between the target entry and this source
         entry.  This returns -1 if they're completely unrelated.
         Here we're using ID distance as an approximation for delta
         size.  */
      this_distance = svn_fs_id_distance (t_entry->id, this_entry->id);

      /* If these nodes are completely unrelated, move along. */
      if (this_distance == -1)
        continue;

      /* If this is the first related node we've found, or just a
         closer node than previously discovered, update our
         best_distance tracker. */
      if ((best_distance == -1) || (this_distance < best_distance))
        {
          best_distance = this_distance;
          best_entry = this_entry;
        }
    }

  /* If our best distance is still reflects no ancestry, return a NULL
     entry to the caller, else return the best entry we found. */
  *s_entry = ((*distance = best_distance) == -1) ? 0 : best_entry;

  /* Destroy local allocation subpool. */
  svn_pool_destroy (subpool);

  return SVN_NO_ERROR;
}


/* Emit deltas to turn SOURCE_PATH into TARGET_PATH.  Assume that
   DIR_BATON represents the directory we're constructing to the editor
   in the context C.  */
static svn_error_t *
delta_dirs (struct context *c, 
            void *dir_baton,
            const char *source_path, 
            const char *target_path,
            apr_pool_t *pool)
{
  apr_hash_t *s_entries = 0, *t_entries = 0;
  apr_hash_index_t *hi;
  apr_pool_t *subpool;

  /* Compare the property lists.  */
  SVN_ERR (delta_proplists (c, source_path, target_path,
                            change_dir_prop, dir_baton, pool));

  /* Get the list of entries in each of source and target.  */
  if (target_path)
    {
      SVN_ERR (svn_fs_dir_entries (&t_entries, c->target_root,
                                   target_path, pool));
    }
  else
    {
      /* Return a viscious error. */
      abort();
    }

  if (source_path)
    {
      SVN_ERR (svn_fs_dir_entries (&s_entries, c->source_root,
                                   source_path, pool));
    }

  /* Make a subpool for local allocations. */
  subpool = svn_pool_create (pool);

  /* Loop over the hash of entries in the target, searching for its
     partner in the source.  If we find the matching partner entry,
     use editor calls to replace the one in target with a new version
     if necessary, then remove that entry from the source entries
     hash.  If we can't find a related node in the source, we use
     editor calls to add the entry as a new item in the target.
     Having handled all the entries that exist in target, any entries
     still remaining the source entries hash represent entries that no
     longer exist in target.  Use editor calls to delete those entries
     from the target tree. */
  for (hi = apr_hash_first (pool, t_entries); hi; hi = apr_hash_next (hi))
    {
      const svn_fs_dirent_t *s_entry, *t_entry;
      const void *key;
      void *val;
      apr_ssize_t klen;
      svn_stringbuf_t *target_fullpath =
        svn_stringbuf_create (target_path, subpool);
          
      /* KEY is the entry name in target, VAL the dirent */
      apr_hash_this (hi, &key, &klen, &val);
      t_entry = val;

      svn_path_add_component_nts (target_fullpath, t_entry->name);

      /* Can we find something with the same name in the source
         entries hash? */
      if (s_entries 
          && ((s_entry = apr_hash_get (s_entries, key, klen)) != 0))
        {
          int distance;
          int is_dir;
          SVN_ERR (svn_fs_is_dir (&is_dir,
                                  c->target_root, target_fullpath->data,
                                  subpool));

          if (c->recurse || !is_dir)
            {

              /* Check the distance between the ids.  

                 0 means they are the same id, and this is a noop.

                 -1 means they are unrelated, so try to find an ancestor
                 elsewhere in the directory.  Theoretically, using an
                 ancestor as a baseline will reduce the size of the deltas.

                 Any other positive value means the nodes are related
                 through ancestry, so go ahead and do the replace
                 directly.  */
              distance = svn_fs_id_distance (s_entry->id, t_entry->id);
              if (distance == 0)
                {
                  /* no-op */
                }
              else if (distance == -1)
                {
                  svn_fs_dirent_t *best_entry;
                  int best_distance = distance;

                  /* If we are allowed to use copyfrom args, try to
                     find a related entry that we might use as an
                     optimization over simply deleting the old thing
                     and add the new one. */
                  if (c->use_copyfrom_args)
                    {
                      SVN_ERR (find_nearest_entry (&best_entry, &best_distance,
                                                   c, source_path, 
                                                   target_path, t_entry, 
                                                   subpool));
                    }

                  /* If we did't find a related node (or simply didn't
                     look), just delete this entry and create a new
                     one from scratch.  Else, replace this entry with
                     the related node we found (sending any changes
                     that might exist between the two). */
                  if (best_distance == -1)
                    {
                      SVN_ERR (delete (c, dir_baton, t_entry->name, subpool));
                      SVN_ERR (add_file_or_dir 
                               (c, dir_baton, NULL, NULL, 
                                target_path, t_entry->name, subpool));
                    }
                  else
                    {
                      SVN_ERR (replace_file_or_dir 
                               (c, dir_baton,
                                source_path,
                                best_entry->name,
                                target_path,
                                t_entry->name,
                                subpool));
                    } 
                }
              else
                {
                  SVN_ERR (replace_file_or_dir
                           (c, dir_baton, 
                            source_path,
                            s_entry->name,
                            target_path,
                            t_entry->name,
                            subpool));
                }
            }

          /*  Remove the entry from the source_hash. */
          apr_hash_set (s_entries, key, APR_HASH_KEY_STRING, NULL);
        }            
      else
        {
          int is_dir;
          SVN_ERR (svn_fs_is_dir (&is_dir, c->target_root,
                                  target_fullpath->data, subpool));

          if (c->recurse || !is_dir)
            {
              /* We didn't find an entry with this name in the source
                 entries hash.  This must be something new that needs to
                 be added. */
              svn_fs_dirent_t *best_entry;
              int best_distance = -1;

              /* If we're allowed to do so, let's first check to see
                 if we can find an ancestor from which to copy this
                 new entry. */
              if (c->use_copyfrom_args)
                {
                  SVN_ERR (find_nearest_entry (&best_entry, &best_distance,
                                               c, source_path, 
                                               target_path, t_entry, subpool));
                }

              /* Add (with history if we found an ancestor) this new
                 entry. */
              if (best_distance == -1)
                SVN_ERR (add_file_or_dir 
                         (c, dir_baton, NULL, NULL,
                          target_path, t_entry->name,
                          subpool));
              else
                SVN_ERR (add_file_or_dir
                         (c, dir_baton, 
                          source_path,
                          best_entry->name,
                          target_path, 
                          t_entry->name,
                          subpool));
            } 
        }

      /* Clear out our subpool for the next iteration... */
      svn_pool_clear (subpool);
    }

  /* All that is left in the source entries hash are things that need
     to be deleted.  Delete them.  */
  if (s_entries)
    {
      for (hi = apr_hash_first (pool, s_entries); hi; hi = apr_hash_next (hi))
        {
          const svn_fs_dirent_t *s_entry;
          const void *key;
          void *val;
          apr_ssize_t klen;
          svn_stringbuf_t *source_fullpath = svn_stringbuf_create (source_path,
                                                                   subpool);
          int is_dir;
          
          /* KEY is the entry name in source, VAL the dirent */
          apr_hash_this (hi, &key, &klen, &val);
          s_entry = val;
          svn_path_add_component_nts (source_fullpath, s_entry->name);

          /* Do we actually want to delete the dir if we're non-recursive? */
          SVN_ERR (svn_fs_is_dir (&is_dir,
                                  c->source_root,
                                  source_fullpath->data,
                                  subpool));

          if (c->recurse || !is_dir)
            {
              SVN_ERR (delete (c, dir_baton, s_entry->name, subpool));
            }
        }
    }

  /* Destroy local allocation subpool. */
  svn_pool_destroy (subpool);

  return SVN_NO_ERROR;
}



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