/*
 * copy.c:  copy/move wrappers around wc 'copy' functionality.
 *
 * ====================================================================
 * 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. ***/

#include <string.h>
#include <assert.h>
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_string.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_path.h"
#include "client.h"


/*** Code. ***/

/*
 * if (not exist src_path)
 *   return ERR_BAD_SRC error
 *
 * if (exist dst_path)
 *   {
 *     if (dst_path is directory)
 *       copy src_path into dst_path as basename (src_path)
 *     else
 *       return ERR_OBSTRUCTION error
 *   }
 * else
 *   copy src_path into parent_of_dst_path as basename (dst_path)
 *
 * if (this is a move)
 *   delete src_path
 */


/* Copy SRC_PATH into DST_PATH as DST_BASENAME, deleting SRC_PATH
   afterwards if IS_MOVE is TRUE.  Use POOL for all necessary
   allocations. */
static svn_error_t *
wc_to_wc_copy (svn_stringbuf_t *src_path,
               svn_stringbuf_t *dst_path,
               svn_boolean_t is_move,
               svn_wc_notify_func_t notify_func,
               void *notify_baton,
               apr_pool_t *pool)
{
  svn_node_kind_t src_kind, dst_kind;
  svn_stringbuf_t *unused, *parent = dst_path, *basename;

  /* Verify that SRC_PATH exists. */
  SVN_ERR (svn_io_check_path (src_path->data, &src_kind, pool));
  if (src_kind == svn_node_none)
    return svn_error_createf (SVN_ERR_UNKNOWN_NODE_KIND, 0, NULL, pool,
                              "path `%s' does not exist.", src_path->data);

  /* If DST_PATH does not exist, then its basename will become a new
     file or dir added to its parent (possibly an implicit '.').  If
     DST_PATH is a dir, then SRC_PATH's basename will become a new
     file or dir within DST_PATH itself.  Else if it's a file, just
     error out. */
  SVN_ERR (svn_io_check_path (dst_path->data, &dst_kind, pool));
  if (dst_kind == svn_node_none)
    svn_path_split (dst_path, &parent, &basename, pool);
  else if (dst_kind == svn_node_dir)
    svn_path_split (src_path, &unused, &basename, pool);
  else
    return svn_error_createf (SVN_ERR_ENTRY_EXISTS, 0, NULL, pool,
                              "file `%s' already exists.", dst_path->data);

  /* Perform the copy and (optionally) delete. */
  SVN_ERR (svn_wc_copy (src_path, parent, basename,
                        notify_func, notify_baton, pool));
  if (is_move)
    {
      apr_status_t apr_err;

      SVN_ERR (svn_wc_delete (src_path,
                              notify_func, notify_baton, pool));

      if (src_kind == svn_node_file)
        {
          apr_err = apr_file_remove (src_path->data, pool);
          if (apr_err)
            return svn_error_createf (apr_err, 0, NULL, pool, 
                                      "error deleting %s", src_path->data);
        }
      /* else do nothing;  we don't want to blow away a directory,
         because 'svn revert' wouldn't be able to undo such a thing. */      
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
repos_to_repos_copy (svn_client_commit_info_t **commit_info,
                     svn_stringbuf_t *src_url, 
                     const svn_client_revision_t *src_revision, 
                     svn_stringbuf_t *dst_url, 
                     svn_client_auth_baton_t *auth_baton,
                     svn_stringbuf_t *message,
                     svn_boolean_t is_move,
                     apr_pool_t *pool)
{
  svn_stringbuf_t *top_url, *src_rel, *dst_rel, *basename, *unused;
  apr_array_header_t *src_pieces = NULL, *dst_pieces = NULL;
  svn_revnum_t youngest;
  void *ra_baton, *sess;
  svn_ra_plugin_t *ra_lib;
  svn_node_kind_t src_kind, dst_kind;
  const svn_delta_editor_t *editor;
  void *edit_baton;
  void *root_baton, *baton;
  void **batons;
  int i = 0;
  svn_revnum_t committed_rev = SVN_INVALID_REVNUM;
  const char *committed_date = NULL;
  const char *committed_author = NULL;
  svn_revnum_t src_revnum;
  svn_stringbuf_t *piece, *telepath;

  /* ### TODO:  Currently, this function will violate the depth-first
     rule of editors when doing a move of something up into one of its
     grandparent directories, such as:

        svn mv http://server/repos/dir1/dir2/file http://server/repos/dir1

     While it seems to work just fine, we might want to evaluate this
     from a purely "correctness" standpoint.
  */

  /* We have to open our session to the longest path common to both
     SRC_URL and DST_URL in the repository so we can do existence
     checks on both paths, and so we can operate on both paths in the
     case of a move. */
  top_url = svn_path_get_longest_ancestor (src_url, dst_url, pool);

  /* Get the portions of the SRC and DST URLs that are relative to
     TOP_URL. */
  src_rel = svn_path_is_child (top_url, src_url, pool);
  if (src_rel)
    {
      src_pieces = svn_path_decompose (src_rel, pool);
      if ((! src_pieces) || (! src_pieces->nelts))
        return svn_error_createf 
          (SVN_ERR_WC_PATH_NOT_FOUND, 0, NULL, pool,
           "error decomposing relative path `%s'", src_rel->data);
    }

  dst_rel = svn_path_is_child (top_url, dst_url, pool);
  if (dst_rel)
    {
      dst_pieces = svn_path_decompose (dst_rel, pool);
      if ((! dst_pieces) || (! dst_pieces->nelts))
        return svn_error_createf 
          (SVN_ERR_WC_PATH_NOT_FOUND, 0, NULL, pool,
           "error decomposing relative path `%s'", dst_rel->data);
    }

  /* Allocate room for the root baton, the pieces of the
     source's or destination's path, and the destination itself. */
  {
    int num, num2;
    num = src_pieces ? src_pieces->nelts : 0;
    if (((num2 = (dst_pieces ? dst_pieces->nelts : 0))) > num)
      num = num2;

    batons = apr_palloc (pool, sizeof (void *) * (num + 2));
  }

  /* Get the RA vtable that matches URL. */
  SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
  SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, top_url->data, pool));

  /* Open an RA session for the URL. Note that we don't have a local
     directory, nor a place to put temp files or store the auth data. */
  SVN_ERR (svn_client__open_ra_session (&sess, ra_lib, top_url, NULL,
                                        NULL, FALSE, FALSE, TRUE, 
                                        auth_baton, pool));

  /* Pass null for the path, to ensure error if trying to get a
     revision based on the working copy. */
  SVN_ERR (svn_client__get_revision_number
           (&src_revnum, ra_lib, sess, src_revision, NULL, pool));

  SVN_ERR (ra_lib->get_latest_revnum (sess, &youngest));

  /* Use YOUNGEST for copyfrom args if not provided. */
  if (! SVN_IS_VALID_REVNUM (src_revnum))
    src_revnum = youngest;
  
  /* Verify that SRC_URL exists in the repository. */
  SVN_ERR (ra_lib->check_path (&src_kind, sess,
                               src_rel ? src_rel->data : NULL, src_revnum));
  if (src_kind == svn_node_none)
    return svn_error_createf 
      (SVN_ERR_FS_NOT_FOUND, 0, NULL, pool,
       "path `%s' does not exist in revision `%ld'",
       src_url->data, src_revnum);

  /* Figure out the basename that will result from this operation. */
  SVN_ERR (ra_lib->check_path (&dst_kind, sess, 
                               dst_rel ? dst_rel->data : NULL, youngest));
  if (dst_kind == svn_node_none)
    {
      svn_path_split (dst_url, &unused, &basename, pool);
      dst_pieces->nelts--; /* hack - where's apr_array_pop()? */
    }
  else if (dst_kind == svn_node_dir)
    svn_path_split (src_url, &unused, &basename, pool);
  else
    return svn_error_createf (SVN_ERR_FS_ALREADY_EXISTS, 0, NULL, pool,
                              "file `%s' already exists.", dst_url->data);

  /* Fetch RA commit editor. */
  SVN_ERR (ra_lib->get_commit_editor (sess, &editor, &edit_baton,
                                      &committed_rev,
                                      &committed_date,
                                      &committed_author,
                                      message));

  /* Initialize telepath to an empty string that's as big as our
     biggest relative target (we don't want to have to realloc this
     thing. */
  if (src_rel->len > dst_rel->len)
    telepath = svn_stringbuf_dup (src_rel, pool);
  else
    telepath = svn_stringbuf_dup (dst_rel, pool);
  svn_stringbuf_setempty (telepath);

  /* Drive that editor, baby! */
  SVN_ERR (editor->open_root (edit_baton, youngest, pool, &root_baton));

  /* Stuff the root baton here for convenience. */
  batons[i] = root_baton;

  /* Open directories down to the place where we need to make our
     copy. */
  if (dst_pieces && dst_pieces->nelts)
    {
      /* open_directory() all the way down to DST's parent. */
      while (i < dst_pieces->nelts)
        {
          piece = (((svn_stringbuf_t **)(dst_pieces)->elts)[i]);
          svn_path_add_component (telepath, piece);
          SVN_ERR (editor->open_directory (telepath->data, batons[i], 
                                           youngest, pool, &(batons[i + 1])));
          i++;
        }
    }
  /* Add our file/dir with copyfrom history. */
  svn_path_add_component (telepath, basename);
  if (src_kind == svn_node_dir)
    {
      SVN_ERR (editor->add_directory (telepath->data, batons[i], src_url->data,
                                      src_revnum, pool, &baton));
      SVN_ERR (editor->close_directory (baton));
    }
  else
    {
      SVN_ERR (editor->add_file (telepath->data, batons[i], src_url->data,
                                 src_revnum, pool, &baton));
      SVN_ERR (editor->close_file (baton));
    }

  /* Now, close up all those batons (except the root
     baton). */
  while (i)
    {
      SVN_ERR (editor->close_directory (batons[i]));
      batons[i--] = NULL;
    }

  /* If this was a move, we need to remove the SRC_URL. */
  svn_stringbuf_setempty (telepath);
  if (is_move)
    {
      /* If SRC_PIECES is NULL, we're trying to move a directory into
         itself (or one of its chidren...we should have caught that by
         now). */
      assert (src_pieces != NULL);

      /* open_directory() all the way down to SRC's parent. */
      while (i < (src_pieces->nelts - 1))
        {
          piece = (((svn_stringbuf_t **)(src_pieces)->elts)[i]);
          svn_path_add_component (telepath, piece);
          SVN_ERR (editor->open_directory (telepath->data, batons[i], 
                                           youngest, pool, &(batons[i + 1])));
          i++;
        }
          
      /* Delete SRC. */
      piece = (((svn_stringbuf_t **)(src_pieces)->elts)[i]);
      svn_path_add_component (telepath, piece);
      SVN_ERR (editor->delete_entry (telepath->data, SVN_INVALID_REVNUM, 
                                     batons[i], pool));

      /* Now, close up all those batons (except the root
         baton). */
      while (i)
        {
          SVN_ERR (editor->close_directory (batons[i--]));
        }
    }

  /* Turn off the lights, close up the shop, and go home. */
  SVN_ERR (editor->close_directory (batons[0]));
  SVN_ERR (editor->close_edit (edit_baton));

  /* Fill in the commit_info structure. */
  *commit_info = svn_client__make_commit_info (committed_rev,
                                               committed_author,
                                               committed_date,
                                               pool);

  SVN_ERR (ra_lib->close (sess));

  return SVN_NO_ERROR;
}



static svn_error_t *
unlock_dirs (apr_hash_t *locked_dirs,
             apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  /* Split if there's nothing to be done. */
  if (! locked_dirs)
    return SVN_NO_ERROR;

  /* Clean up any locks. */
  for (hi = apr_hash_first (pool, locked_dirs); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t keylen;
      void *val;
      svn_stringbuf_t *strkey;

      apr_hash_this (hi, &key, &keylen, &val);
      strkey = svn_stringbuf_ncreate ((const char *)key, keylen, pool);
      SVN_ERR (svn_wc_unlock (strkey, pool));
    }

  return SVN_NO_ERROR;
}  


static svn_error_t *
remove_tmpfiles (apr_hash_t *tempfiles,
                 apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  /* Split if there's nothing to be done. */
  if (! tempfiles)
    return SVN_NO_ERROR;

  /* Clean up any tempfiles. */
  for (hi = apr_hash_first (pool, tempfiles); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t keylen;
      void *val;
      svn_node_kind_t kind;

      apr_hash_this (hi, &key, &keylen, &val);
      SVN_ERR (svn_io_check_path ((const char *)key, &kind, pool));
      if (kind == svn_node_file)
        SVN_ERR (svn_io_remove_file ((const char *)key, pool));
    }

  return SVN_NO_ERROR;
}



static svn_error_t *
reconcile_errors (svn_error_t *commit_err,
                  svn_error_t *unlock_err,
                  svn_error_t *cleanup_err,
                  apr_pool_t *pool)
{
  svn_error_t *err;

  /* Early release (for good behavior). */
  if (! (commit_err || unlock_err || cleanup_err))
    return SVN_NO_ERROR;

  /* If there was a commit error, start off our error chain with
     that. */
  if (commit_err)
    {
      commit_err = svn_error_quick_wrap 
        (commit_err, "Commit failed (details follow):");
      err = commit_err;
    }

  /* Else, create a new "general" error that will head off the errors
     that follow. */
  else
    err = svn_error_create (SVN_ERR_GENERAL, 0, NULL, pool,
                            "Commit succeeded, but other errors follow:");

  /* If there was an unlock error... */
  if (unlock_err)
    {
      /* Wrap the error with some headers. */
      unlock_err = svn_error_quick_wrap 
        (unlock_err, "Error unlocking locked dirs (details follow):");

      /* Append this error to the chain. */
      svn_error_compose (err, unlock_err);
    }

  /* If there was a cleanup error... */
  if (cleanup_err)
    {
      /* Wrap the error with some headers. */
      cleanup_err = svn_error_quick_wrap 
        (cleanup_err, "Error in post-commit clean-up (details follow):");

      /* Append this error to the chain. */
      svn_error_compose (err, cleanup_err);
    }

  return err;
}



static svn_error_t *
wc_to_repos_copy (svn_client_commit_info_t **commit_info,
                  svn_stringbuf_t *src_path, 
                  svn_stringbuf_t *dst_url, 
                  svn_client_auth_baton_t *auth_baton,
                  svn_stringbuf_t *message,
                  const svn_delta_editor_t *before_editor,
                  void *before_edit_baton,
                  const svn_delta_editor_t *after_editor,
                  void *after_edit_baton,
                  apr_pool_t *pool)
{
  svn_stringbuf_t *anchor, *target, *parent, *basename;
  void *ra_baton, *session;
  svn_ra_plugin_t *ra_lib;
  const svn_delta_editor_t *editor;
  void *edit_baton;
  svn_node_kind_t src_kind, dst_kind;
  svn_revnum_t committed_rev = SVN_INVALID_REVNUM;
  const char *committed_date = NULL;
  const char *committed_author = NULL;
  apr_hash_t *committables, *locked_dirs, *tempfiles = NULL;
  apr_array_header_t *commit_items;
  svn_error_t *cmt_err = NULL, *unlock_err = NULL, *cleanup_err = NULL;
  svn_boolean_t commit_in_progress = FALSE;
  svn_stringbuf_t *base_path, *base_url;

  /* Check the SRC_PATH. */
  SVN_ERR (svn_io_check_path (src_path->data, &src_kind, pool));

  /* Split the SRC_PATH into a parent and basename. */
  svn_path_split (src_path, &parent, &basename, pool);
  if (svn_path_is_empty (parent))
    parent = svn_stringbuf_create (".", pool);

  /* Split the DST_URL into an anchor and target. */
  svn_path_split (dst_url, &anchor, &target, pool);

  /* Get the RA vtable that matches URL. */
  SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
  SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, anchor->data, pool));

  /* Open an RA session for the anchor URL. */
  SVN_ERR (svn_client__open_ra_session (&session, ra_lib, anchor, parent,
                                        NULL, TRUE, TRUE, TRUE, 
                                        auth_baton, pool));

  /* Figure out the basename that will result from this operation. */
  SVN_ERR (ra_lib->check_path (&dst_kind, session, target->data,
                               SVN_INVALID_REVNUM));
  
  /* Close the RA session.  We'll re-open it after we've figured out
     the right URL to open. */
  SVN_ERR (ra_lib->close (session));
  session = NULL;

  /* BASE_URL defaults to DST_URL. */
  base_url = svn_stringbuf_dup (dst_url, pool);
  if (dst_kind == svn_node_none)
    {
      /* DST_URL doesn't exist under it's parent URL, so the URL we
         will be creating is DST_URL. */
    }
  else if (dst_kind == svn_node_dir)
    {
      /* DST_URL is an existing directory URL.  The URL we will be
         creating, then, is DST_URL+BASENAME. */
      svn_path_add_component (base_url, basename);
    }
  else
    {
      /* DST_URL is an existing file, which can't be overwritten or
         used as a container, so error out. */
      return svn_error_createf (SVN_ERR_FS_ALREADY_EXISTS, 0, NULL, pool,
                                "file `%s' already exists.", dst_url->data);
    }

  /* Get the absolute path of the WC path. */
  SVN_ERR (svn_path_get_absolute (&base_path, src_path, pool));

  /* Crawl the working copy for commit items. */
  if ((cmt_err = svn_client__get_copy_committables (&committables, 
                                                    &locked_dirs,
                                                    base_url,
                                                    base_path,
                                                    pool)))
    goto cleanup;

  /* ### todo: There should be only one hash entry, which currently
     has a hacked name until we have the entries files storing
     canonical repository URLs.  Then, the hacked name can go away and
     be replaced with a entry->repos (or whereever the entry's
     canonical repos URL is stored). */
  if (! ((commit_items = apr_hash_get (committables, 
                                       SVN_CLIENT__SINGLE_REPOS_NAME, 
                                       APR_HASH_KEY_STRING))))
    goto cleanup;

  /* Sort and condense our COMMIT_ITEMS. */
  if ((cmt_err = svn_client__condense_commit_items (&base_url, 
                                                    commit_items, 
                                                    pool)))
    goto cleanup;

  /* Open an RA session to BASE_URL. */
  if ((cmt_err = svn_client__open_ra_session (&session, ra_lib, base_url, NULL,
                                              commit_items, TRUE, TRUE, TRUE,
                                              auth_baton, pool)))
    goto cleanup;

  /* Fetch RA commit editor, giving it svn_wc_process_committed(). */
  if ((cmt_err = ra_lib->get_commit_editor (session, &editor, &edit_baton, 
                                            &committed_rev, &committed_date, 
                                            &committed_author, message)))
    goto cleanup;

  /* Make a note that we have a commit-in-progress. */
  commit_in_progress = TRUE;

  /* Wrap the resulting editor with BEFORE and AFTER editors. */
  svn_delta_wrap_editor (&editor, &edit_baton,
                         before_editor, before_edit_baton,
                         editor, edit_baton, 
                         after_editor, after_edit_baton, pool);

  /* Perform the commit. */
  cmt_err = svn_client__do_commit (base_url, commit_items, editor, edit_baton, 
                                   NULL, NULL, NULL,
                                   &tempfiles, pool);

  commit_in_progress = FALSE;

  /* Sleep for one second to ensure timestamp integrity. */
  apr_sleep (APR_USEC_PER_SEC * 1);

 cleanup:
  /* Abort the commit if it is still in progress. */
  if (commit_in_progress)
    editor->abort_edit (edit_baton); /* ignore return value */

  /* We were committing to RA, so close the session. */
  if (session)
    ra_lib->close (session);

  /* Unlock any remaining locked dirs. */
  if (locked_dirs)
    unlock_err = unlock_dirs (locked_dirs, pool);

  /* Remove any outstanding temporary text-base files. */
  if (tempfiles)
    cleanup_err = remove_tmpfiles (tempfiles, pool);

  /* Fill in the commit_info structure */
  *commit_info = svn_client__make_commit_info (committed_rev, 
                                               committed_author, 
                                               committed_date, pool);

  return reconcile_errors (cmt_err, unlock_err, cleanup_err, pool);
}


static svn_error_t *
repos_to_wc_copy (svn_stringbuf_t *src_url,
                  const svn_client_revision_t *src_revision,
                  svn_stringbuf_t *dst_path, 
                  svn_client_auth_baton_t *auth_baton,
                  const svn_delta_editor_t *before_editor,
                  void *before_edit_baton,
                  const svn_delta_editor_t *after_editor,
                  void *after_edit_baton,
                  svn_wc_notify_func_t notify_func,
                  void *notify_baton,
                  apr_pool_t *pool)
{
  void *ra_baton, *sess;
  svn_ra_plugin_t *ra_lib;
  svn_node_kind_t src_kind, dst_kind;
  svn_revnum_t src_revnum;

  /* Get the RA vtable that matches URL. */
  SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
  SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, src_url->data, pool));

  /* Open a repository session to the given URL. We do not (yet) have a
     working copy, so we don't have a corresponding path and tempfiles
     cannot go into the admin area. We do want to store the resulting
     auth data, though, once the WC is built. */
  SVN_ERR (svn_client__open_ra_session (&sess, ra_lib, src_url, NULL,
                                        NULL, TRUE, FALSE, TRUE, 
                                        auth_baton, pool));
      
  /* Pass null for the path, to ensure error if trying to get a
     revision based on the working copy. */
  SVN_ERR (svn_client__get_revision_number
           (&src_revnum, ra_lib, sess, src_revision, NULL, pool));

  /* Verify that SRC_URL exists in the repository. */
  SVN_ERR (ra_lib->check_path (&src_kind, sess, "", src_revnum));
  if (src_kind == svn_node_none)
    {
      if (SVN_IS_VALID_REVNUM (src_revnum))
        return svn_error_createf
          (SVN_ERR_FS_NOT_FOUND, 0, NULL, pool,
           "path `%s' not found in revision `%ld'", src_url->data, src_revnum);
      else
        return svn_error_createf
          (SVN_ERR_FS_NOT_FOUND, 0, NULL, pool,
           "path `%s' not found in head revision", src_url->data);
    }

  /* There are two interfering sets of cases to watch out for here:
   *
   * First set:
   *
   *   1) If DST_PATH does not exist, then great.  We're going to
   *      create a new entry in its parent.
   *   2) If it does exist, then it must be a directory and we're
   *      copying to a new entry inside that dir (the entry's name is
   *      the basename of SRC_URL).
   *
   * But while that's all going on, we must also remember:
   *
   *   A) If SRC_URL is a directory in the repository, we can check
   *      it out directly, no problem.
   *   B) If SRC_URL is a file, we have to manually get the editor
   *      started, since there won't be a root to open.
   *
   * I'm going to ignore B for the moment, and implement cases 1 and
   * 2 under A.
   */

  /* First, figure out about dst. */
  SVN_ERR (svn_io_check_path (dst_path->data, &dst_kind, pool));
  if (dst_kind == svn_node_dir)
    {
      svn_stringbuf_t *unused, *basename;
      svn_path_split (src_url, &unused, &basename, pool);

      /* We shouldn't affect the caller's dst_path, so dup first and
         then extend. */
      dst_path = svn_stringbuf_dup (dst_path, pool);
      svn_path_add_component (dst_path, basename);
    }
  else if (dst_kind != svn_node_none)  /* must be a file */
    return svn_error_createf (SVN_ERR_ENTRY_EXISTS, 0, NULL, pool,
                              "file `%s' already exists.", dst_path->data);

  /* Now that dst_path has possibly been reset, check that there's
     nothing in the way of the upcoming checkout. */
  SVN_ERR (svn_io_check_path (dst_path->data, &dst_kind, pool));
  if (dst_kind != svn_node_none)
    return svn_error_createf (SVN_ERR_WC_OBSTRUCTED_UPDATE, 0, NULL, pool,
                              "`%s' is in the way", dst_path->data);

  if (src_kind == svn_node_dir)
    {    
      const svn_delta_editor_t *editor;
      void *edit_baton;
      const svn_delta_editor_t *wrap_editor;
      void *wrap_edit_baton;
      const svn_delta_edit_fns_t *wrapped_old_editor;
      void *wrapped_old_edit_baton;

      /* Get a checkout editor and wrap it. */
      SVN_ERR (svn_wc_get_checkout_editor (dst_path,
                                           src_url,
                                           src_revnum,
                                           1,
                                           &editor,
                                           &edit_baton,
                                           pool));
      
      svn_delta_wrap_editor (&wrap_editor, &wrap_edit_baton,
                             before_editor, before_edit_baton,
                             editor, edit_baton,
                             after_editor, after_edit_baton, pool);

      /* ### todo:  This is a TEMPORARY wrapper around our editor so we
         can use it with an old driver. */
      svn_delta_compat_wrap (&wrapped_old_editor, &wrapped_old_edit_baton, 
                             wrap_editor, wrap_edit_baton, pool);

      
      /* Check out the new tree.  The parent dir will get no entry, so
         it will be as if the new tree isn't really there yet. */
      SVN_ERR (ra_lib->do_checkout (sess, src_revnum, 1, 
                                    wrapped_old_editor,
                                    wrapped_old_edit_baton));

      if (! SVN_IS_VALID_REVNUM(src_revnum))
        {
          /* If we just checked out from the "head" revision, that's fine,
             but we don't want to pass a '-1' as a copyfrom_rev to
             svn_wc_add().  That function will dump it right into the
             entry, and when we try to commit later on, the
             'add-dir-with-history' step will be -very- unhappy; it only
             accepts specific revisions.
             
             On the other hand, we *could* say that -1 is a legitimate
             copyfrom_rev, but I think that's bogus.  Somebody made a copy
             from a particular revision;  if they wait a long time to
             commit, it would be terrible if the copied happened from a
             newer revision!! */
          
          /* We just did a checkout; whatever revision we just got, that
             should be the copyfrom_revision when we commit later. */
          svn_wc_entry_t *d_entry;
          SVN_ERR (svn_wc_entry (&d_entry, dst_path, pool));
          src_revnum = d_entry->revision;
        }

    } /* end directory case */

  else if (src_kind == svn_node_file)
    {
      apr_status_t status;
      svn_stream_t *fstream;
      apr_file_t *fp;
      svn_revnum_t fetched_rev = 0;
      apr_hash_t *props;
      apr_hash_index_t *hi;
      
      /* Open DST_PATH for writing. */
      status = apr_file_open (&fp, dst_path->data, (APR_CREATE | APR_WRITE),
                              APR_OS_DEFAULT, pool);
      if (status)
        return svn_error_createf (status, 0, NULL, pool,
                                  "failed to open file '%s' for writing.",
                                  dst_path->data);

      /* Create a generic stream that operates on this file.  */
      fstream = svn_stream_from_aprfile (fp, pool);
      
      /* Have the RA layer 'push' data at this stream.  We pass a
         relative path of "", because we opened SRC_URL, which is
         already the full URL to the file. */         
      SVN_ERR (ra_lib->get_file (sess, "", src_revnum, fstream, 
                                 &fetched_rev, &props));

      for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi)) 
        {
          const void *key;
          void *val;
          int len;
          enum svn_prop_kind kind;

          apr_hash_this (hi, &key, NULL, &val);

          /* We only want to set 'normal' props.  For now, we're
             ignoring any wc props (they're not needed when we commit
             an addition), and we're ignoring entry props (they're
             written to the entries file as part of the post-commit
             processing).  */
          kind = svn_property_kind (&len, key);
          if (kind == svn_prop_regular_kind)
            SVN_ERR (svn_wc_prop_set (key, val, dst_path->data, pool));
        }

      /* Close the file. */
      status = apr_file_close (fp);
      if (status)
        return svn_error_createf (status, 0, NULL, pool,
                                  "failed to close file '%s'.",
                                  dst_path->data);   
     
      /* Also, if SRC_REVNUM is invalid ('head'), then FETCHED_REV is now
         equal to the revision that was actually retrieved.  This is
         the value we want to use as 'copyfrom_rev' in the call to
         svn_wc_add() below. */
      if (! SVN_IS_VALID_REVNUM (src_revnum))
        src_revnum = fetched_rev;
    }

  /* Free the RA session. */
  SVN_ERR (ra_lib->close (sess));
      
  /* Schedule the new item for addition-with-history.

     If the new item is a directory, the URLs will be recursively
     rewritten, wcprops removed, and everything marked as 'copied'.
     See comment in svn_wc_add()'s doc about whether svn_wc_add is the
     appropriate place for this. */
  SVN_ERR (svn_wc_add (dst_path, src_url, src_revnum,
                       notify_func, notify_baton, pool));


  return SVN_NO_ERROR;
}


static svn_error_t *
setup_copy (svn_client_commit_info_t **commit_info,
            svn_stringbuf_t *src_path,
            const svn_client_revision_t *src_revision,
            svn_stringbuf_t *dst_path,
            svn_client_auth_baton_t *auth_baton,
            svn_client_get_commit_log_t log_msg_func,
            void *log_msg_baton,
            const svn_delta_editor_t *before_editor,
            void *before_edit_baton,
            const svn_delta_editor_t *after_editor,
            void *after_edit_baton,
            svn_boolean_t is_move,
            svn_wc_notify_func_t notify_func,
            void *notify_baton,
            apr_pool_t *pool)
{
  svn_boolean_t src_is_url, dst_is_url;
  svn_string_t path_str;
  svn_stringbuf_t *message;

  /* Are either of our paths URLs? */
  path_str.data = src_path->data;
  path_str.len = src_path->len;
  src_is_url = svn_path_is_url (&path_str);
  path_str.data = dst_path->data;
  path_str.len = dst_path->len;
  dst_is_url = svn_path_is_url (&path_str);

  if (is_move)
    {
      if (src_is_url == dst_is_url)
        {
          if (svn_path_is_child (src_path, dst_path, pool))
            return svn_error_createf
              (SVN_ERR_UNSUPPORTED_FEATURE, 0, NULL, pool,
               "cannot move path '%s' into its own child '%s'",
               src_path->data, dst_path->data);
          if (svn_stringbuf_compare (src_path, dst_path))
            return svn_error_createf
              (SVN_ERR_UNSUPPORTED_FEATURE, 0, NULL, pool,
               "cannot move path '%s' into itself",
               src_path->data);
        }
      else
        {
          /* Disallow moves between the working copy and the repository. */
          return svn_error_create 
            (SVN_ERR_UNSUPPORTED_FEATURE, 0, NULL, pool,
             "no support for repos <--> working copy moves");
        }

      /* It doesn't make sense to specify revisions in a move. */

      /* ### todo: this check could fail wrongly.  For example,
         someone could pass in an svn_client_revision_number that just
         happens to be the HEAD.  It's fair enough to punt then, IMHO,
         and just demand that the user not specify a revision at all;
         beats mucking up this function with RA calls and such. */ 
      if ((src_revision->kind != svn_client_revision_unspecified)
          || (src_revision->kind != svn_client_revision_unspecified))
        {
          return svn_error_create
            (SVN_ERR_UNSUPPORTED_FEATURE, 0, NULL, pool,
             "cannot specify revisions with move operations");
        }
    }

  /* Create a new commit item and add it to the array. */
  if (dst_is_url && log_msg_func)
    {
      svn_client_commit_item_t *item;
      apr_array_header_t *commit_items 
        = apr_array_make (pool, 1, sizeof (item));
      
      item = apr_pcalloc (pool, sizeof (*item));
      item->url = svn_stringbuf_dup (dst_path, pool);
      item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
      (*((svn_client_commit_item_t **) apr_array_push (commit_items))) 
        = item;
      
      SVN_ERR ((*log_msg_func) (&message, commit_items, 
                                log_msg_baton, pool));
      if (! message)
        return SVN_NO_ERROR;
    }
  else
    message = svn_stringbuf_create ("", pool);

  /* Now, call the right handler for the operation. */
  if ((! src_is_url) && (! dst_is_url))
    SVN_ERR (wc_to_wc_copy (src_path, dst_path, is_move,
                            notify_func, notify_baton,
                            pool));

  else if ((! src_is_url) && (dst_is_url))
    SVN_ERR (wc_to_repos_copy (commit_info, src_path, dst_path, 
                               auth_baton, message, 
                               before_editor, before_edit_baton,
                               after_editor, after_edit_baton,
                               pool));

  else if ((src_is_url) && (! dst_is_url))
    SVN_ERR (repos_to_wc_copy (src_path, src_revision, 
                               dst_path, auth_baton,
                               before_editor, before_edit_baton,
                               after_editor, after_edit_baton,
                               notify_func, notify_baton,
                               pool));

  else
    SVN_ERR (repos_to_repos_copy (commit_info, src_path, src_revision,
                                  dst_path, auth_baton, message, is_move,
                                  pool));

  return SVN_NO_ERROR;
}



/* Public Interfaces */

svn_error_t *
svn_client_copy (svn_client_commit_info_t **commit_info,
                 svn_stringbuf_t *src_path,
                 const svn_client_revision_t *src_revision,
                 svn_stringbuf_t *dst_path,
                 svn_client_auth_baton_t *auth_baton,
                 svn_client_get_commit_log_t log_msg_func,
                 void *log_msg_baton,
                 const svn_delta_editor_t *before_editor,
                 void *before_edit_baton,
                 const svn_delta_editor_t *after_editor,
                 void *after_edit_baton,
                 svn_wc_notify_func_t notify_func,
                 void *notify_baton,
                 apr_pool_t *pool)
{
  return setup_copy (commit_info, 
                     src_path, src_revision, dst_path, auth_baton, 
                     log_msg_func, log_msg_baton,
                     before_editor, before_edit_baton,
                     after_editor, after_edit_baton,
                     FALSE /* is_move */,
                     notify_func, notify_baton,
                     pool);
}


svn_error_t *
svn_client_move (svn_client_commit_info_t **commit_info,
                 svn_stringbuf_t *src_path,
                 const svn_client_revision_t *src_revision,
                 svn_stringbuf_t *dst_path,
                 svn_client_auth_baton_t *auth_baton,
                 svn_client_get_commit_log_t log_msg_func,
                 void *log_msg_baton,
                 svn_wc_notify_func_t notify_func,
                 void *notify_baton,
                 apr_pool_t *pool)
{
  return setup_copy (commit_info,
                     src_path, src_revision, dst_path, auth_baton,
                     log_msg_func, log_msg_baton,
                     NULL, NULL,  /* no before_editor, before_edit_baton */
                     NULL, NULL,  /* no after_editor, after_edit_baton */
                     TRUE /* is_move */,
                     notify_func, notify_baton,
                     pool);
}






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