/*
 * shelf2-cmd.c -- Shelving commands.
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

/* We define this here to remove any further warnings about the usage of
   experimental functions in this file. */
#define SVN_EXPERIMENTAL

#include "svn_client.h"
#include "svn_error_codes.h"
#include "svn_error.h"
#include "svn_hash.h"
#include "svn_path.h"
#include "svn_props.h"
#include "svn_pools.h"
#include "svn_utf.h"

#include "shelf2-cmd.h"
#include "cl.h"

#include "svn_private_config.h"
#include "private/svn_sorts_private.h"
#include "private/svn_client_private.h"
#include "private/svn_client_shelf2.h"


/* Open the newest version of SHELF; error if no versions found. */
static svn_error_t *
get_newest_version_existing(svn_client__shelf2_version_t **shelf_version_p,
                            svn_client__shelf2_t *shelf,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
{
  SVN_ERR(svn_client__shelf2_get_newest_version(shelf_version_p, shelf,
                                              result_pool, scratch_pool));
  if (!*shelf_version_p)
    {
      return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                               _("Shelf '%s': no versions found"),
                               shelf->name);
    }

  return SVN_NO_ERROR;
}

/* Fetch the next argument. */
static svn_error_t *
get_next_argument(const char **arg,
                  apr_getopt_t *os,
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
{
  apr_array_header_t *args;

  SVN_ERR(svn_opt_parse_num_args(&args, os, 1, scratch_pool));
  SVN_ERR(svn_utf_cstring_to_utf8(arg,
                                  APR_ARRAY_IDX(args, 0, const char *),
                                  result_pool));
  return SVN_NO_ERROR;
}

/* Parse the remaining arguments as paths relative to a WC.
 *
 * TARGETS are relative to current working directory.
 *
 * Set *targets_by_wcroot to a hash mapping (char *)wcroot_abspath to
 * (apr_array_header_t *)array of relpaths relative to that WC root.
 */
static svn_error_t *
targets_relative_to_wcs(apr_hash_t **targets_by_wcroot_p,
                        apr_array_header_t *targets,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  apr_hash_t *targets_by_wcroot = apr_hash_make(result_pool);
  int i;

  /* Make each target relative to the WC root. */
  for (i = 0; i < targets->nelts; i++)
    {
      const char *target = APR_ARRAY_IDX(targets, i, const char *);
      const char *wcroot_abspath;
      apr_array_header_t *paths;

      SVN_ERR(svn_dirent_get_absolute(&target, target, result_pool));
      SVN_ERR(svn_client_get_wc_root(&wcroot_abspath, target,
                                     ctx, result_pool, scratch_pool));
      paths = svn_hash_gets(targets_by_wcroot, wcroot_abspath);
      if (! paths)
        {
          paths = apr_array_make(result_pool, 0, sizeof(char *));
          svn_hash_sets(targets_by_wcroot, wcroot_abspath, paths);
        }
      target = svn_dirent_skip_ancestor(wcroot_abspath, target);

      if (target)
        APR_ARRAY_PUSH(paths, const char *) = target;
    }
  *targets_by_wcroot_p = targets_by_wcroot;
  return SVN_NO_ERROR;
}

/* Return targets relative to a WC. Error if they refer to more than one WC. */
static svn_error_t *
targets_relative_to_a_wc(const char **wc_root_abspath_p,
                         apr_array_header_t **paths_p,
                         apr_getopt_t *os,
                         const apr_array_header_t *known_targets,
                         svn_client_ctx_t *ctx,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
{
  apr_array_header_t *targets;
  apr_hash_t *targets_by_wcroot;
  apr_hash_index_t *hi;

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      known_targets,
                                                      ctx, FALSE, result_pool));
  svn_opt_push_implicit_dot_target(targets, result_pool);

  SVN_ERR(targets_relative_to_wcs(&targets_by_wcroot, targets,
                                  ctx, result_pool, scratch_pool));
  if (apr_hash_count(targets_by_wcroot) != 1)
    return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
                            _("All targets must be in the same WC"));

  hi = apr_hash_first(scratch_pool, targets_by_wcroot);
  *wc_root_abspath_p = apr_hash_this_key(hi);
  *paths_p = apr_hash_this_val(hi);
  return SVN_NO_ERROR;
}

/* Return a human-friendly description of DURATION.
 */
static char *
friendly_age_str(apr_time_t mtime,
                 apr_time_t time_now,
                 apr_pool_t *result_pool)
{
  int minutes = (int)((time_now - mtime) / 1000000 / 60);
  char *s;

  if (minutes >= 60 * 24)
    s = apr_psprintf(result_pool,
                     Q_("%d day ago", "%d days ago",
                        minutes / 60 / 24),
                     minutes / 60 / 24);
  else if (minutes >= 60)
    s = apr_psprintf(result_pool,
                     Q_("%d hour ago", "%d hours ago",
                        minutes / 60),
                     minutes / 60);
  else
    s = apr_psprintf(result_pool,
                     Q_("%d minute ago", "%d minutes ago",
                        minutes),
                     minutes);
  return s;
}

/* A comparison function for svn_sort__hash(), comparing the mtime of two
   svn_client_shelf_info_t's. */
static int
compare_shelf_infos_by_mtime(const svn_sort__item_t *a,
                             const svn_sort__item_t *b)
{
  svn_client__shelf2_info_t *a_val = a->value;
  svn_client__shelf2_info_t *b_val = b->value;

  return (a_val->mtime < b_val->mtime)
    ? -1 : (a_val->mtime > b_val->mtime) ? 1 : 0;
}

/* Return a list of shelves sorted by their mtime, oldest first.
 */
static svn_error_t *
list_sorted_by_date(apr_array_header_t **list,
                    const char *local_abspath,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *scratch_pool)
{
  apr_hash_t *shelf_infos;

  SVN_ERR(svn_client__shelf2_list(&shelf_infos, local_abspath,
                                ctx, scratch_pool, scratch_pool));
  *list = svn_sort__hash(shelf_infos,
                         compare_shelf_infos_by_mtime,
                         scratch_pool);
  return SVN_NO_ERROR;
}

/*  */
static svn_error_t *
stats(svn_client__shelf2_t *shelf,
      int version,
      svn_client__shelf2_version_t *shelf_version,
      apr_time_t time_now,
      svn_boolean_t with_logmsg,
      apr_pool_t *scratch_pool)
{
  char *age_str;
  char *version_str;
  apr_hash_t *paths;
  const char *paths_str = "";

  if (! shelf_version)
    {
      return SVN_NO_ERROR;
    }

  age_str = friendly_age_str(shelf_version->mtime, time_now, scratch_pool);
  if (version == shelf->max_version)
    version_str = apr_psprintf(scratch_pool,
                               _("version %d"), version);
  else
    version_str = apr_psprintf(scratch_pool,
                               Q_("version %d of %d", "version %d of %d",
                                  shelf->max_version),
                               version, shelf->max_version);
  SVN_ERR(svn_client__shelf2_paths_changed(&paths, shelf_version,
                                         scratch_pool, scratch_pool));
  paths_str = apr_psprintf(scratch_pool,
                           Q_("%d path changed", "%d paths changed",
                              apr_hash_count(paths)),
                           apr_hash_count(paths));
  SVN_ERR(svn_cmdline_printf(scratch_pool,
                             "%-30s %s, %s, %s\n",
                             shelf->name, version_str, age_str, paths_str));

  if (with_logmsg)
    {
      char *log_message;

      SVN_ERR(svn_client__shelf2_get_log_message(&log_message, shelf,
                                               scratch_pool));
      if (log_message)
        {
          SVN_ERR(svn_cmdline_printf(scratch_pool,
                                     _(" %.50s\n"),
                                     log_message));
        }
    }

  return SVN_NO_ERROR;
}

/* Display a list of shelves */
static svn_error_t *
shelves_list(const char *local_abspath,
             svn_boolean_t quiet,
             svn_client_ctx_t *ctx,
             apr_pool_t *scratch_pool)
{
  apr_time_t time_now = apr_time_now();
  apr_array_header_t *list;
  int i;

  SVN_ERR(list_sorted_by_date(&list,
                              local_abspath, ctx, scratch_pool));

  for (i = 0; i < list->nelts; i++)
    {
      const svn_sort__item_t *item = &APR_ARRAY_IDX(list, i, svn_sort__item_t);
      const char *name = item->key;
      svn_client__shelf2_t *shelf;
      svn_client__shelf2_version_t *shelf_version;

      SVN_ERR(svn_client__shelf2_open_existing(&shelf, name, local_abspath,
                                             ctx, scratch_pool));
      SVN_ERR(svn_client__shelf2_get_newest_version(&shelf_version, shelf,
                                                  scratch_pool, scratch_pool));
      if (quiet)
        SVN_ERR(svn_cmdline_printf(scratch_pool, "%s\n", shelf->name));
      else if (!shelf_version)
        SVN_ERR(svn_cmdline_printf(scratch_pool, "%-30s no versions\n",
                                   shelf->name));
      else
        SVN_ERR(stats(shelf, shelf->max_version, shelf_version, time_now,
                      TRUE /*with_logmsg*/, scratch_pool));
      SVN_ERR(svn_client__shelf2_close(shelf, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Print info about each checkpoint of the shelf named NAME.
 */
static svn_error_t *
shelf_log(const char *name,
          const char *local_abspath,
          svn_client_ctx_t *ctx,
          apr_pool_t *scratch_pool)
{
  apr_time_t time_now = apr_time_now();
  svn_client__shelf2_t *shelf;
  apr_array_header_t *versions;
  int i;

  SVN_ERR(svn_client__shelf2_open_existing(&shelf, name, local_abspath,
                                         ctx, scratch_pool));
  SVN_ERR(svn_client__shelf2_get_all_versions(&versions, shelf,
                                            scratch_pool, scratch_pool));
  for (i = 0; i < versions->nelts; i++)
    {
      svn_client__shelf2_version_t *shelf_version
        = APR_ARRAY_IDX(versions, i, void *);

      SVN_ERR(stats(shelf, i + 1, shelf_version, time_now,
                    FALSE /*with_logmsg*/, scratch_pool));
    }

  SVN_ERR(svn_client__shelf2_close(shelf, scratch_pool));
  return SVN_NO_ERROR;
}

/* Find the name of the youngest shelf.
 */
static svn_error_t *
name_of_youngest(const char **name_p,
                 const char *local_abspath,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  apr_array_header_t *list;
  const svn_sort__item_t *youngest_item;

  SVN_ERR(list_sorted_by_date(&list,
                              local_abspath, ctx, scratch_pool));
  if (list->nelts == 0)
    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
                            _("No shelves found"));

  youngest_item = &APR_ARRAY_IDX(list, list->nelts - 1, svn_sort__item_t);
  *name_p = apr_pstrdup(result_pool, youngest_item->key);
  return SVN_NO_ERROR;
}

struct status_baton
{
  /* These fields correspond to the ones in the
     svn_cl__print_status() interface. */
  const char *target_abspath;
  const char *target_path;

  svn_boolean_t quiet;  /* don't display statuses while shelving them */
  int num_paths_shelved;
  int num_paths_not_shelved;
  svn_client_ctx_t *ctx;
};

/* A status callback function for printing STATUS for PATH. */
static svn_error_t *
print_status(void *baton,
             const char *path,
             const svn_client_status_t *status,
             apr_pool_t *scratch_pool)
{
  struct status_baton *sb = baton;
  unsigned int conflicts;

  return svn_cl__print_status(sb->target_abspath, sb->target_path,
                              path, status,
                              TRUE /*suppress_externals_placeholders*/,
                              FALSE /*detailed*/,
                              FALSE /*show_last_committed*/,
                              TRUE /*skip_unrecognized*/,
                              FALSE /*repos_locks*/,
                              &conflicts, &conflicts, &conflicts,
                              sb->ctx,
                              scratch_pool);
}

/* A callback function for shelved paths. */
static svn_error_t *
was_shelved(void *baton,
            const char *path,
            const svn_client_status_t *status,
            apr_pool_t *scratch_pool)
{
  struct status_baton *sb = baton;

  if (!sb->quiet)
    {
      SVN_ERR(print_status(baton, path, status, scratch_pool));
    }

  ++sb->num_paths_shelved;
  return SVN_NO_ERROR;
}

/* A callback function for not-shelved paths. */
static svn_error_t *
was_not_shelved(void *baton,
                const char *path,
                const svn_client_status_t *status,
                apr_pool_t *scratch_pool)
{
  struct status_baton *sb = baton;

  SVN_ERR(print_status(baton, path, status, scratch_pool));
  SVN_ERR(svn_cmdline_printf(scratch_pool, "      >   not shelved\n"));
  ++sb->num_paths_not_shelved;
  return SVN_NO_ERROR;
}

/** Shelve/save a new version of changes.
 *
 * Shelve in shelf @a name the local modifications found by @a paths,
 * @a depth, @a changelists. Revert the shelved changes from the WC
 * unless @a keep_local is true.
 *
 * If no local modifications are found, throw an error.
 *
 * If @a dry_run is true, don't actually do it.
 *
 * Report in @a *new_version_p the new version number (or, with dry run,
 * what it would be).
 */
static svn_error_t *
shelve(int *new_version_p,
       const char *name,
       const apr_array_header_t *paths,
       svn_depth_t depth,
       const apr_array_header_t *changelists,
       apr_hash_t *revprop_table,
       svn_boolean_t keep_local,
       svn_boolean_t dry_run,
       svn_boolean_t quiet,
       const char *local_abspath,
       svn_client_ctx_t *ctx,
       apr_pool_t *scratch_pool)
{
  svn_client__shelf2_t *shelf;
  svn_client__shelf2_version_t *previous_version;
  svn_client__shelf2_version_t *new_version;
  struct status_baton sb;

  SVN_ERR(svn_client__shelf2_open_or_create(&shelf,
                                          name, local_abspath,
                                          ctx, scratch_pool));
  SVN_ERR(svn_client__shelf2_get_newest_version(&previous_version, shelf,
                                              scratch_pool, scratch_pool));

  if (! quiet)
    {
      SVN_ERR(svn_cmdline_printf(scratch_pool, keep_local
                                 ? _("--- Save a new version of '%s' in WC root '%s'\n")
                                 : _("--- Shelve '%s' in WC root '%s'\n"),
                                 shelf->name, shelf->wc_root_abspath));
      SVN_ERR(stats(shelf, shelf->max_version, previous_version, apr_time_now(),
                    TRUE /*with_logmsg*/, scratch_pool));
    }

  sb.target_abspath = shelf->wc_root_abspath;
  sb.target_path = "";
  sb.quiet = quiet;
  sb.num_paths_shelved = 0;
  sb.num_paths_not_shelved = 0;
  sb.ctx = ctx;

  if (! quiet)
    SVN_ERR(svn_cmdline_printf(scratch_pool,
                               keep_local ? _("--- Saving...\n")
                               : _("--- Shelving...\n")));
  SVN_ERR(svn_client__shelf2_save_new_version3(&new_version, shelf,
                                             paths, depth, changelists,
                                             was_shelved, &sb,
                                             was_not_shelved, &sb,
                                             scratch_pool));
  if (sb.num_paths_not_shelved > 0)
    {
      SVN_ERR(svn_client__shelf2_delete_newer_versions(shelf, previous_version,
                                                     scratch_pool));
      SVN_ERR(svn_client__shelf2_close(shelf, scratch_pool));
      return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                               Q_("%d path could not be shelved",
                                  "%d paths could not be shelved",
                                  sb.num_paths_not_shelved),
                               sb.num_paths_not_shelved);
    }
  if (sb.num_paths_shelved == 0
      || ! new_version)
    {
      SVN_ERR(svn_client__shelf2_close(shelf, scratch_pool));
      return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                               keep_local ? _("No local modifications could be saved")
                               : _("No local modifications could be shelved"));
    }

  /* Un-apply the changes, if required. */
  if (!keep_local)
    {
      SVN_ERR(svn_client__shelf2_unapply(new_version,
                                       dry_run, scratch_pool));
    }

  /* Fetch the log message and any other revprops */
  if (ctx->log_msg_func3)
    {
      const char *tmp_file;
      apr_array_header_t *commit_items
        = apr_array_make(scratch_pool, 1, sizeof(void *));
      const char *message = "";

      SVN_ERR(ctx->log_msg_func3(&message, &tmp_file, commit_items,
                                 ctx->log_msg_baton3, scratch_pool));
      /* Abort the shelving if the log message callback requested so. */
      if (! message)
        return SVN_NO_ERROR;

      if (message && !dry_run)
        {
          svn_string_t *propval = svn_string_create(message, scratch_pool);

          if (! revprop_table)
            revprop_table = apr_hash_make(scratch_pool);
          svn_hash_sets(revprop_table, SVN_PROP_REVISION_LOG, propval);
        }
    }

  SVN_ERR(svn_client__shelf2_revprop_set_all(shelf, revprop_table, scratch_pool));

  if (new_version_p)
    *new_version_p = shelf->max_version;

  if (dry_run)
    {
      SVN_ERR(svn_client__shelf2_delete_newer_versions(shelf, previous_version,
                                                     scratch_pool));
    }

  SVN_ERR(svn_client__shelf2_close(shelf, scratch_pool));
  return SVN_NO_ERROR;
}

/* Return the single character representation of STATUS.
 * (Similar to subversion/svn/status.c:generate_status_code()
 * and subversion/tests/libsvn_client/client-test.c:status_to_char().) */
static char
status_to_char(enum svn_wc_status_kind status)
{
  switch (status)
    {
    case svn_wc_status_none:        return '.';
    case svn_wc_status_unversioned: return '?';
    case svn_wc_status_normal:      return ' ';
    case svn_wc_status_added:       return 'A';
    case svn_wc_status_missing:     return '!';
    case svn_wc_status_deleted:     return 'D';
    case svn_wc_status_replaced:    return 'R';
    case svn_wc_status_modified:    return 'M';
    case svn_wc_status_merged:      return 'G';
    case svn_wc_status_conflicted:  return 'C';
    case svn_wc_status_ignored:     return 'I';
    case svn_wc_status_obstructed:  return '~';
    case svn_wc_status_external:    return 'X';
    case svn_wc_status_incomplete:  return ':';
    default:                        return '*';
    }
}

/* Throw an error if any path affected by SHELF_VERSION gives a conflict
 * when applied (as a dry-run) to the WC. */
static svn_error_t *
test_apply(svn_client__shelf2_version_t *shelf_version,
           svn_client_ctx_t *ctx,
           apr_pool_t *scratch_pool)
{
  apr_hash_t *paths;
  apr_hash_index_t *hi;

  SVN_ERR(svn_client__shelf2_paths_changed(&paths, shelf_version,
                                         scratch_pool, scratch_pool));
  for (hi = apr_hash_first(scratch_pool, paths); hi; hi = apr_hash_next(hi))
    {
      const char *path = apr_hash_this_key(hi);
      svn_boolean_t conflict;

      SVN_ERR(svn_client__shelf2_test_apply_file(&conflict, shelf_version, path,
                                               scratch_pool));
      if (conflict)
        {
          char *to_wc_abspath
            = svn_dirent_join(shelf_version->shelf->wc_root_abspath, path,
                              scratch_pool);
          svn_wc_status3_t *status;

          SVN_ERR(svn_wc_status3(&status, ctx->wc_ctx, to_wc_abspath,
                                 scratch_pool, scratch_pool));
          return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                                   _("Shelved path '%s' already has "
                                     "status '%c' in the working copy"),
                                   path, status_to_char(status->node_status));
        }
    }
  return SVN_NO_ERROR;
}

/** Restore/unshelve a given or newest version of changes.
 *
 * Restore local modifications from shelf @a name version @a arg,
 * or the newest version is @a arg is null.
 *
 * If @a dry_run is true, don't actually do it.
 *
 * Error if any path would have a conflict, unless @a force_if_conflict.
 */
static svn_error_t *
shelf_restore(const char *name,
              const char *arg,
              svn_boolean_t dry_run,
              svn_boolean_t quiet,
              svn_boolean_t force_if_conflict,
              const char *local_abspath,
              svn_client_ctx_t *ctx,
              apr_pool_t *scratch_pool)
{
  int version, old_version;
  apr_time_t time_now = apr_time_now();
  svn_client__shelf2_t *shelf;
  svn_client__shelf2_version_t *shelf_version;

  SVN_ERR(svn_client__shelf2_open_existing(&shelf, name, local_abspath,
                                         ctx, scratch_pool));

  old_version = shelf->max_version;
  if (arg)
    {
      SVN_ERR(svn_cstring_atoi(&version, arg));
      SVN_ERR(svn_client__shelf2_version_open(&shelf_version,
                                            shelf, version,
                                            scratch_pool, scratch_pool));
    }
  else
    {
      version = shelf->max_version;
      SVN_ERR(get_newest_version_existing(&shelf_version, shelf,
                                          scratch_pool, scratch_pool));
    }

  if (! quiet)
    {
      SVN_ERR(svn_cmdline_printf(scratch_pool,
                                 _("--- Unshelve '%s' in WC root '%s'\n"),
                                 shelf->name, shelf->wc_root_abspath));
      SVN_ERR(stats(shelf, version, shelf_version, time_now,
                    TRUE /*with_logmsg*/, scratch_pool));
    }
  if (! force_if_conflict)
    {
      SVN_ERR_W(test_apply(shelf_version, ctx, scratch_pool),
                _("Cannot unshelve/restore, as at least one shelved "
                  "path would conflict with a local modification "
                  "or other status in the working copy"));
    }

  SVN_ERR(svn_client__shelf2_apply(shelf_version,
                                 dry_run, scratch_pool));

  if (! dry_run)
    {
      SVN_ERR(svn_client__shelf2_delete_newer_versions(shelf, shelf_version,
                                                     scratch_pool));
    }

  if (!quiet)
    {
      if (version < old_version)
        SVN_ERR(svn_cmdline_printf(scratch_pool,
                                   Q_("restored '%s' version %d and deleted %d newer version\n",
                                      "restored '%s' version %d and deleted %d newer versions\n",
                                      old_version - version),
                                   name, version, old_version - version));
      else
        SVN_ERR(svn_cmdline_printf(scratch_pool,
                                   _("restored '%s' version %d (the newest version)\n"),
                                   name, version));
    }

  SVN_ERR(svn_client__shelf2_close(shelf, scratch_pool));
  return SVN_NO_ERROR;
}

static svn_error_t *
shelf_diff(const char *name,
           const char *arg,
           const char *local_abspath,
           svn_boolean_t summarize,
           svn_depth_t depth,
           svn_boolean_t ignore_ancestry,
           svn_client_ctx_t *ctx,
           apr_pool_t *scratch_pool)
{
  svn_client__shelf2_t *shelf;
  svn_client__shelf2_version_t *shelf_version;
  svn_stream_t *stream, *errstream;
  svn_diff_tree_processor_t *diff_processor;

  SVN_ERR(svn_client__shelf2_open_existing(&shelf, name, local_abspath,
                                         ctx, scratch_pool));

  if (arg)
    {
      int version;

      SVN_ERR(svn_cstring_atoi(&version, arg));
      SVN_ERR(svn_client__shelf2_version_open(&shelf_version,
                                            shelf, version,
                                            scratch_pool, scratch_pool));
    }
  else
    {
      SVN_ERR(get_newest_version_existing(&shelf_version, shelf,
                                          scratch_pool, scratch_pool));
    }

  SVN_ERR(svn_stream_for_stdout(&stream, scratch_pool));
  errstream = svn_stream_empty(scratch_pool);

  if (summarize)
    {
      svn_client_diff_summarize_func_t func;
      void *baton;

      SVN_ERR(svn_cl__get_diff_summary_writer(&func, &baton,
                                              FALSE /*xml*/,
                                              FALSE /*ignore_properties*/,
                                              "" /*anchor/prefix*/,
                                              scratch_pool, scratch_pool));
      SVN_ERR(svn_client__get_diff_summarize_callbacks(&diff_processor,
                                                       func, baton,
                                                       scratch_pool,
                                                       scratch_pool));
    }
  else
    {
      SVN_ERR(svn_client__get_diff_writer_svn(
                &diff_processor,
                NULL /*anchor*/,
                "", "", /*orig_path_1, orig_path_2,*/
                NULL /*options*/,
                "" /*relative_to_dir*/,
                FALSE /*no_diff_added*/,
                FALSE /*no_diff_deleted*/,
                FALSE /*show_copies_as_adds*/,
                FALSE /*ignore_content_type*/,
                FALSE /*ignore_properties*/,
                FALSE /*properties_only*/,
                TRUE /*pretty_print_mergeinfo*/,
                svn_cmdline_output_encoding(scratch_pool),
                stream, errstream,
                ctx, scratch_pool));
    }

  SVN_ERR(svn_client__shelf2_diff(shelf_version, "",
                                 depth, ignore_ancestry,
                                 diff_processor, scratch_pool));
  SVN_ERR(svn_stream_close(stream));

  SVN_ERR(svn_client__shelf2_close(shelf, scratch_pool));
  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
shelf_drop(const char *name,
           const char *local_abspath,
           svn_boolean_t dry_run,
           svn_boolean_t quiet,
           svn_client_ctx_t *ctx,
           apr_pool_t *scratch_pool)
{
  SVN_ERR(svn_client__shelf2_delete(name, local_abspath, dry_run,
                                  ctx, scratch_pool));
  if (! quiet)
    SVN_ERR(svn_cmdline_printf(scratch_pool,
                               _("deleted '%s'\n"),
                               name));
  return SVN_NO_ERROR;
}

/*  */
static svn_error_t *
shelf_shelve(int *new_version,
             const char *name,
             apr_array_header_t *targets,
             svn_depth_t depth,
             apr_array_header_t *changelists,
             apr_hash_t *revprop_table,
             svn_boolean_t keep_local,
             svn_boolean_t dry_run,
             svn_boolean_t quiet,
             svn_client_ctx_t *ctx,
             apr_pool_t *scratch_pool)
{
  const char *local_abspath;

  if (depth == svn_depth_unknown)
    depth = svn_depth_infinity;

  SVN_ERR(svn_cl__check_targets_are_local_paths(targets));

  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, scratch_pool));

  svn_opt_push_implicit_dot_target(targets, scratch_pool);

  /* ### TODO: check all paths are in same WC; for now use first path */
  SVN_ERR(svn_dirent_get_absolute(&local_abspath,
                                  APR_ARRAY_IDX(targets, 0, char *),
                                  scratch_pool));

  SVN_ERR(shelve(new_version, name,
                 targets, depth, changelists,
                 revprop_table,
                 keep_local, dry_run, quiet,
                 local_abspath, ctx, scratch_pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
svn_cl__shelf_shelve(apr_getopt_t *os,
                     void *baton,
                     apr_pool_t *pool);

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_save(apr_getopt_t *os,
                   void *baton,
                   apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;

  opt_state->keep_local = TRUE;
  SVN_ERR(svn_cl__shelf_shelve(os, baton, pool));
  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_shelve(apr_getopt_t *os,
                     void *baton,
                     apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  const char *name;
  apr_array_header_t *targets;

  if (opt_state->quiet)
    ctx->notify_func2 = NULL; /* Easy out: avoid unneeded work */

  SVN_ERR(get_next_argument(&name, os, pool, pool));

  /* Parse the remaining arguments as paths. */
  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, FALSE, pool));
  {
    int new_version;
    svn_error_t *err;

    if (ctx->log_msg_func3)
      SVN_ERR(svn_cl__make_log_msg_baton(&ctx->log_msg_baton3,
                                         opt_state, NULL, ctx->config,
                                         pool));
    err = shelf_shelve(&new_version, name,
                       targets, opt_state->depth, opt_state->changelists,
                       opt_state->revprop_table,
                       opt_state->keep_local, opt_state->dry_run,
                       opt_state->quiet, ctx, pool);
    if (ctx->log_msg_func3)
      SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3,
                                      err, pool));
    else
      SVN_ERR(err);

    if (! opt_state->quiet)
      {
        if (opt_state->keep_local)
          SVN_ERR(svn_cmdline_printf(pool,
                                     _("saved '%s' version %d\n"),
                                     name, new_version));
        else
          SVN_ERR(svn_cmdline_printf(pool,
                                     _("shelved '%s' version %d\n"),
                                     name, new_version));
      }
  }

  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_unshelve(apr_getopt_t *os,
                       void *baton,
                       apr_pool_t *scratch_pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  const char *local_abspath;
  const char *name;
  const char *arg = NULL;

  SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", scratch_pool));

  if (os->ind < os->argc)
    {
      SVN_ERR(get_next_argument(&name, os, scratch_pool, scratch_pool));
    }
  else
    {
      SVN_ERR(name_of_youngest(&name,
                               local_abspath, ctx, scratch_pool, scratch_pool));
      SVN_ERR(svn_cmdline_printf(scratch_pool,
                                 _("unshelving the youngest shelf, '%s'\n"),
                                 name));
    }

  /* Which checkpoint number? */
  if (os->ind < os->argc)
    SVN_ERR(get_next_argument(&arg, os, scratch_pool, scratch_pool));

  if (os->ind < os->argc)
    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                            _("Too many arguments"));

  if (opt_state->quiet)
    ctx->notify_func2 = NULL; /* Easy out: avoid unneeded work */

  SVN_ERR(shelf_restore(name, arg,
                        opt_state->dry_run, opt_state->quiet,
                        opt_state->force /*force_already_modified*/,
                        local_abspath, ctx, scratch_pool));

  if (opt_state->drop)
    {
      SVN_ERR(shelf_drop(name, local_abspath,
                         opt_state->dry_run, opt_state->quiet,
                         ctx, scratch_pool));
    }
  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_list(apr_getopt_t *os,
                   void *baton,
                   apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  apr_array_header_t *targets = NULL;
  apr_pool_t *iterpool = svn_pool_create(pool);
  int i;

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, FALSE, pool));
  /* Add "." if user passed 0 arguments */
  svn_opt_push_implicit_dot_target(targets, pool);

  for (i = 0; i < targets->nelts; ++i)
    {
      const char *local_abspath;
      const char *target = APR_ARRAY_IDX(targets, i, const char *);

      svn_pool_clear(iterpool);

      SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));

      SVN_ERR(shelves_list(local_abspath,
                           opt_state->quiet,
                           ctx, iterpool));
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* "svn shelf-list-by-paths [PATH...]"
 *
 * TARGET_RELPATHS are all within the same WC, relative to WC_ROOT_ABSPATH.
 */
static svn_error_t *
shelf_list_by_paths(apr_array_header_t *target_relpaths,
                    const char *wc_root_abspath,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *scratch_pool)
{
  apr_array_header_t *shelves;
  apr_hash_t *paths_to_shelf_name = apr_hash_make(scratch_pool);
  apr_array_header_t *array;
  int i;

  SVN_ERR(list_sorted_by_date(&shelves,
                              wc_root_abspath, ctx, scratch_pool));

  /* Check paths are valid */
  for (i = 0; i < target_relpaths->nelts; i++)
    {
      char *target_relpath = APR_ARRAY_IDX(target_relpaths, i, char *);

      if (svn_path_is_url(target_relpath))
        return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
                                 _("'%s' is not a local path"), target_relpath);
      SVN_ERR_ASSERT(svn_relpath_is_canonical(target_relpath));
    }

  /* Find the most recent shelf for each affected path */
  for (i = 0; i < shelves->nelts; i++)
    {
      svn_sort__item_t *item = &APR_ARRAY_IDX(shelves, i, svn_sort__item_t);
      const char *name = item->key;
      svn_client__shelf2_t *shelf;
      svn_client__shelf2_version_t *shelf_version;
      apr_hash_t *shelf_paths;
      int j;

      SVN_ERR(svn_client__shelf2_open_existing(&shelf,
                                              name, wc_root_abspath,
                                              ctx, scratch_pool));
      SVN_ERR(svn_client__shelf2_get_newest_version(&shelf_version, shelf,
                                                   scratch_pool, scratch_pool));
      if (!shelf_version)
        continue;
      SVN_ERR(svn_client__shelf2_paths_changed(&shelf_paths,
                                              shelf_version,
                                              scratch_pool, scratch_pool));
      for (j = 0; j < target_relpaths->nelts; j++)
        {
          char *target_relpath = APR_ARRAY_IDX(target_relpaths, j, char *);
          apr_hash_index_t *hi;

          for (hi = apr_hash_first(scratch_pool, shelf_paths);
               hi; hi = apr_hash_next(hi))
            {
              const char *shelf_path = apr_hash_this_key(hi);

              if (svn_relpath_skip_ancestor(target_relpath, shelf_path))
                {
                  if (! svn_hash_gets(paths_to_shelf_name, shelf_path))
                    {
                      svn_hash_sets(paths_to_shelf_name, shelf_path, shelf->name);
                    }
                }
            }
        }
    }

  /* Print the results. */
  array = svn_sort__hash(paths_to_shelf_name,
                         svn_sort_compare_items_as_paths,
                         scratch_pool);
  for (i = 0; i < array->nelts; i++)
    {
      svn_sort__item_t *item = &APR_ARRAY_IDX(array, i, svn_sort__item_t);
      const char *path = item->key;
      const char *name = item->value;

      SVN_ERR(svn_cmdline_printf(scratch_pool, "%-20.20s %s\n",
                                 name,
                                 svn_dirent_local_style(path, scratch_pool)));
    }
  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_list_by_paths(apr_getopt_t *os,
                            void *baton,
                            apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  const char *wc_root_abspath;
  apr_array_header_t *targets;

  /* Parse the remaining arguments as paths. */
  SVN_ERR(targets_relative_to_a_wc(&wc_root_abspath, &targets,
                                   os, opt_state->targets,
                                   ctx, pool, pool));

  SVN_ERR(shelf_list_by_paths(targets, wc_root_abspath, ctx, pool));
  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_diff(apr_getopt_t *os,
                   void *baton,
                   apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  const char *local_abspath;
  const char *name;
  const char *arg = NULL;

  SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", pool));

  SVN_ERR(get_next_argument(&name, os, pool, pool));

  /* Which checkpoint number? */
  if (os->ind < os->argc)
    SVN_ERR(get_next_argument(&arg, os, pool, pool));

  if (os->ind < os->argc)
    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                            _("Too many arguments"));

  SVN_ERR(shelf_diff(name, arg, local_abspath,
                     opt_state->diff.summarize,
                     opt_state->depth, opt_state->ignore_ancestry,
                     ctx, pool));

  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_drop(apr_getopt_t *os,
                   void *baton,
                   apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  const char *name;
  apr_array_header_t *targets = NULL;
  apr_pool_t *iterpool = svn_pool_create(pool);
  int i;

  SVN_ERR(get_next_argument(&name, os, pool, pool));

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, FALSE, pool));
  svn_opt_push_implicit_dot_target(targets, pool);

  for (i = 0; i < targets->nelts; ++i)
    {
      const char *local_abspath;
      const char *target = APR_ARRAY_IDX(targets, i, const char *);

      svn_pool_clear(iterpool);

      SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));
      SVN_ERR(shelf_drop(name, local_abspath,
                         opt_state->dry_run, opt_state->quiet,
                         ctx, iterpool));
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* This implements the `svn_opt_subcommand_t' interface. */
static svn_error_t *
svn_cl__shelf_log(apr_getopt_t *os,
                  void *baton,
                  apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  const char *name;
  apr_array_header_t *targets = NULL;
  apr_pool_t *iterpool = svn_pool_create(pool);
  int i;

  SVN_ERR(get_next_argument(&name, os, pool, pool));

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, FALSE, pool));
  svn_opt_push_implicit_dot_target(targets, pool);

  for (i = 0; i < targets->nelts; ++i)
    {
      const char *local_abspath;
      const char *target = APR_ARRAY_IDX(targets, i, const char *);

      svn_pool_clear(iterpool);

      SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));
      SVN_ERR(shelf_log(name, local_abspath, ctx, iterpool));
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

const svn_opt_subcommand_desc3_t
svn_cl__cmd_table_shelf2[] =
{
  { "x-shelf-diff", svn_cl__shelf_diff, {0}, {N_(
     "Show shelved changes as a diff.\n"
     "usage: x-shelf-diff SHELF [VERSION]\n"
     "\n"), N_(
     "  Show the changes in SHELF:VERSION (default: latest) as a diff.\n"
     "\n"), N_(
     "  See also: 'svn diff --cl=svn:shelf:SHELF' which supports most options of\n"
     "  'svn diff'.\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
    {opt_summarize},
  },

  { "x-shelf-drop", svn_cl__shelf_drop, {0}, {N_(
     "Delete a shelf.\n"
     "usage: x-shelf-drop SHELF [PATH ...]\n"
     "\n"), N_(
     "  Delete the shelves named SHELF from the working copies containing PATH\n"
     "  (default PATH is '.')\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
  },

  { "x-shelf-list", svn_cl__shelf_list, {"x-shelves"}, {N_(
     "List shelves.\n"
     "usage: x-shelf-list [PATH ...]\n"
     "\n"), N_(
     "  List shelves for each working copy containing PATH (default is '.')\n"
     "  Include the first line of any log message and some details about the\n"
     "  contents of the shelf, unless '-q' is given.\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
    {'q', 'v'}
  },

  { "x-shelf-list-by-paths", svn_cl__shelf_list_by_paths, {0}, {N_(
     "List which shelf affects each path.\n"
     "usage: x-shelf-list-by-paths [PATH...]\n"
     "\n"), N_(
     "  List which shelf most recently affects each path below the given PATHs.\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
  },

  { "x-shelf-log", svn_cl__shelf_log, {0}, {N_(
     "Show the versions of a shelf.\n"
     "usage: x-shelf-log SHELF [PATH...]\n"
     "\n"), N_(
     "  Show all versions of SHELF for each working copy containing PATH (the\n"
     "  default PATH is '.').\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
    {'q', 'v'}
  },

  { "x-shelf-save", svn_cl__shelf_save, {0}, {N_(
     "Copy local changes onto a new version of a shelf.\n"
     "usage: x-shelf-save SHELF [PATH...]\n"
     "\n"), N_(
     "  Save local changes in the given PATHs as a new version of SHELF.\n"
     "  The shelf's log message can be set with -m, -F, etc.\n"
     "\n"), N_(
     "  The same as 'svn shelve --keep-local'.\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
    {'q', opt_dry_run,
     opt_depth, opt_targets, opt_changelist,
     SVN_CL__LOG_MSG_OPTIONS,
    }
  },

  { "x-shelve", svn_cl__shelf_shelve, {0}, {N_(
     "Move local changes onto a shelf.\n"
     "usage: x-shelve [--keep-local] SHELF [PATH...]\n"
     "\n"), N_(
     "  Save the local changes in the given PATHs to a new or existing SHELF.\n"
     "  Revert those changes from the WC unless '--keep-local' is given.\n"
     "  The shelf's log message can be set with -m, -F, etc.\n"
     "\n"), N_(
     "  'svn shelve --keep-local' is the same as 'svn shelf-save'.\n"
     "\n"), N_(
     "  The kinds of change you can shelve are committable changes to files and\n"
     "  properties, except the following kinds which are not yet supported:\n"
     "     * copies and moves\n"
     "     * mkdir and rmdir\n"
     "  Uncommittable states such as conflicts, unversioned and missing cannot\n"
     "  be shelved.\n"
     "\n"), N_(
     "  To bring back shelved changes, use 'svn unshelve SHELF'.\n"
     "\n"), N_(
     "  Shelves are currently stored under <WC>/.svn/experimental/shelves/ .\n"
     "  (In Subversion 1.10, shelves were stored under <WC>/.svn/shelves/ as\n"
     "  patch files. To recover a shelf created by 1.10, either use a 1.10\n"
     "  client to find and unshelve it, or find the patch file and use any\n"
     "  1.10 or later 'svn patch' to apply it.)\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
    {'q', opt_dry_run, opt_keep_local,
     opt_depth, opt_targets, opt_changelist,
     SVN_CL__LOG_MSG_OPTIONS,
    } },

  { "x-unshelve", svn_cl__shelf_unshelve, {0}, {N_(
     "Copy shelved changes back into the WC.\n"
     "usage: x-unshelve [--drop] [SHELF [VERSION]]\n"
     "\n"), N_(
     "  Apply the changes stored in SHELF to the working copy.\n"
     "  SHELF defaults to the newest shelf.\n"
     "\n"), N_(
     "  Apply the newest version of the shelf, by default. If VERSION is\n"
     "  specified, apply that version and discard all versions newer than that.\n"
     "  In any case, retain the unshelved version and versions older than that\n"
     "  (unless --drop is specified).\n"
     "\n"), N_(
     "  With --drop, delete the entire shelf (like 'svn shelf-drop') after\n"
     "  successfully unshelving with no conflicts.\n"
     "\n"), N_(
     "  The working files involved should be in a clean, unmodified state\n"
     "  before using this command. To roll back to an older version of the\n"
     "  shelf, first ensure any current working changes are removed, such as\n"
     "  by shelving or reverting them, and then unshelve the desired version.\n"
     "\n"), N_(
     "  Unshelve normally refuses to apply any changes if any path involved is\n"
     "  already modified (or has any other abnormal status) in the WC. With\n"
     "  --force, it does not check and may error out and/or produce partial or\n"
     "  unexpected results.\n"
     "\n"), N_(
     "  The shelving feature is EXPERIMENTAL. This command is likely to change\n"
     "  in the next release, and there is no promise of backward compatibility.\n"
    )},
    {opt_drop, 'q', opt_dry_run, opt_force} },

  { NULL, NULL, {0}, {NULL}, {0} }
};

