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

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



/*** Includes. ***/

#include <apr_file_io.h>
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_error.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "client.h"

#include "private/svn_client_private.h"
#include "private/svn_wc_private.h"
#include "private/svn_ra_private.h"

#include "svn_private_config.h"


/*** Code. ***/

/* Baton for find_undeletables */
struct can_delete_baton_t
{
  const char *root_abspath;
  svn_boolean_t target_missing;
};

/* An svn_wc_status_func4_t callback function for finding
   status structures which are not safely deletable. */
static svn_error_t *
find_undeletables(void *baton,
                  const char *local_abspath,
                  const svn_wc_status3_t *status,
                  apr_pool_t *pool)
{
  if (status->node_status == svn_wc_status_missing)
    {
      struct can_delete_baton_t *cdt = baton;

      if (strcmp(cdt->root_abspath, local_abspath) == 0)
        cdt->target_missing = TRUE;
    }

  /* Check for error-ful states. */
  if (status->node_status == svn_wc_status_obstructed)
    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                             _("'%s' is in the way of the resource "
                               "actually under version control"),
                             svn_dirent_local_style(local_abspath, pool));
  else if (! status->versioned)
    return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                             _("'%s' is not under version control"),
                             svn_dirent_local_style(local_abspath, pool));
  else if ((status->node_status == svn_wc_status_added
            || status->node_status == svn_wc_status_replaced)
           && status->text_status == svn_wc_status_normal
           && (status->prop_status == svn_wc_status_normal
               || status->prop_status == svn_wc_status_none))
    {
      /* Unmodified copy. Go ahead, remove it */
    }
  else if (status->node_status != svn_wc_status_normal
           && status->node_status != svn_wc_status_deleted
           && status->node_status != svn_wc_status_missing)
    return svn_error_createf(SVN_ERR_CLIENT_MODIFIED, NULL,
                             _("'%s' has local modifications -- commit or "
                               "revert them first"),
                             svn_dirent_local_style(local_abspath, pool));

  return SVN_NO_ERROR;
}

/* Check whether LOCAL_ABSPATH is an external and raise an error if it is.

   A file external should not be deleted since the file external is
   implemented as a switched file and it would delete the file the
   file external is switched to, which is not the behavior the user
   would probably want.

   A directory external should not be deleted since it is the root
   of a different working copy. */
static svn_error_t *
check_external(const char *local_abspath,
               svn_client_ctx_t *ctx,
               apr_pool_t *scratch_pool)
{
  svn_node_kind_t external_kind;
  const char *defining_abspath;

  SVN_ERR(svn_wc__read_external_info(&external_kind, &defining_abspath, NULL,
                                     NULL, NULL,
                                     ctx->wc_ctx, local_abspath,
                                     local_abspath, TRUE,
                                     scratch_pool, scratch_pool));

  if (external_kind != svn_node_none)
    return svn_error_createf(SVN_ERR_WC_CANNOT_DELETE_FILE_EXTERNAL, NULL,
                             _("Cannot remove the external at '%s'; "
                               "please edit or delete the svn:externals "
                               "property on '%s'"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool),
                             svn_dirent_local_style(defining_abspath,
                                                    scratch_pool));

  return SVN_NO_ERROR;
}

/* Verify that the path can be deleted without losing stuff,
   i.e. ensure that there are no modified or unversioned resources
   under PATH.  This is similar to checking the output of the status
   command.  CTX is used for the client's config options.  POOL is
   used for all temporary allocations. */
static svn_error_t *
can_delete_node(svn_boolean_t *target_missing,
                const char *local_abspath,
                svn_client_ctx_t *ctx,
                apr_pool_t *scratch_pool)
{
  apr_array_header_t *ignores;
  struct can_delete_baton_t cdt;

  /* Use an infinite-depth status check to see if there's anything in
     or under PATH which would make it unsafe for deletion.  The
     status callback function find_undeletables() makes the
     determination, returning an error if it finds anything that shouldn't
     be deleted. */

  SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, scratch_pool));

  cdt.root_abspath = local_abspath;
  cdt.target_missing = FALSE;

  SVN_ERR(svn_wc_walk_status(ctx->wc_ctx,
                             local_abspath,
                             svn_depth_infinity,
                             FALSE /* get_all */,
                             FALSE /* no_ignore */,
                             FALSE /* ignore_text_mod */,
                             ignores,
                             find_undeletables, &cdt,
                             ctx->cancel_func,
                             ctx->cancel_baton,
                             scratch_pool));

  if (target_missing)
    *target_missing = cdt.target_missing;

  return SVN_NO_ERROR;
}


static svn_error_t *
path_driver_cb_func(void **dir_baton,
                    const svn_delta_editor_t *editor,
                    void *edit_baton,
                    void *parent_baton,
                    void *callback_baton,
                    const char *path,
                    apr_pool_t *pool)
{
  *dir_baton = NULL;
  return editor->delete_entry(path, SVN_INVALID_REVNUM, parent_baton, pool);
}

static svn_error_t *
single_repos_delete(svn_ra_session_t *ra_session,
                    const char *base_uri,
                    const apr_array_header_t *relpaths,
                    const apr_hash_t *revprop_table,
                    svn_commit_callback2_t commit_callback,
                    void *commit_baton,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
{
  const svn_delta_editor_t *editor;
  apr_hash_t *commit_revprops;
  void *edit_baton;
  const char *log_msg;
  int i;
  svn_error_t *err;

  /* Create new commit items and add them to the array. */
  if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
    {
      svn_client_commit_item3_t *item;
      const char *tmp_file;
      apr_array_header_t *commit_items
        = apr_array_make(pool, relpaths->nelts, sizeof(item));

      for (i = 0; i < relpaths->nelts; i++)
        {
          const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);

          item = svn_client_commit_item3_create(pool);
          item->url = svn_path_url_add_component2(base_uri, relpath, pool);
          item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
          APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
        }
      SVN_ERR(svn_client__get_log_msg(&log_msg, &tmp_file, commit_items,
                                      ctx, pool));
      if (! log_msg)
        return SVN_NO_ERROR;
    }
  else
    log_msg = "";

  SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
                                           log_msg, ctx, pool));

  /* Fetch RA commit editor */
  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
                        svn_client__get_shim_callbacks(ctx->wc_ctx,
                                                       NULL, pool)));
  SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                    commit_revprops,
                                    commit_callback,
                                    commit_baton,
                                    NULL, TRUE, /* No lock tokens */
                                    pool));

  /* Call the path-based editor driver. */
  err = svn_delta_path_driver3(editor, edit_baton, relpaths, TRUE,
                               path_driver_cb_func, NULL, pool);

  if (err)
    {
      return svn_error_trace(
               svn_error_compose_create(err,
                                        editor->abort_edit(edit_baton, pool)));
    }

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify;
      notify = svn_wc_create_notify_url(base_uri,
                                        svn_wc_notify_commit_finalizing,
                                        pool);
      ctx->notify_func2(ctx->notify_baton2, notify, pool);
    }

  /* Close the edit. */
  return svn_error_trace(editor->close_edit(edit_baton, pool));
}


/* Structure for tracking remote delete targets associated with a
   specific repository. */
struct repos_deletables_t
{
  svn_ra_session_t *ra_session;
  apr_array_header_t *target_uris;
};


static svn_error_t *
delete_urls_multi_repos(const apr_array_header_t *uris,
                        const apr_hash_t *revprop_table,
                        svn_commit_callback2_t commit_callback,
                        void *commit_baton,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *pool)
{
  apr_hash_t *deletables = apr_hash_make(pool);
  apr_pool_t *iterpool;
  apr_hash_index_t *hi;
  int i;

  /* Create a hash mapping repository root URLs -> repos_deletables_t *
     structures.  */
  for (i = 0; i < uris->nelts; i++)
    {
      const char *uri = APR_ARRAY_IDX(uris, i, const char *);
      struct repos_deletables_t *repos_deletables = NULL;
      const char *repos_relpath;
      svn_node_kind_t kind;

      for (hi = apr_hash_first(pool, deletables); hi; hi = apr_hash_next(hi))
        {
          const char *repos_root = apr_hash_this_key(hi);

          repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);
          if (repos_relpath)
            {
              /* Great!  We've found another URI underneath this
                 session.  We'll pick out the related RA session for
                 use later, store the new target, and move on.  */
              repos_deletables = apr_hash_this_val(hi);
              APR_ARRAY_PUSH(repos_deletables->target_uris, const char *) =
                apr_pstrdup(pool, uri);
              break;
            }
        }

      /* If we haven't created a repos_deletable structure for this
         delete target, we need to do.  That means opening up an RA
         session and initializing its targets list.  */
      if (!repos_deletables)
        {
          svn_ra_session_t *ra_session = NULL;
          const char *repos_root;
          apr_array_header_t *target_uris;

          /* Open an RA session to (ultimately) the root of the
             repository in which URI is found.  */
          SVN_ERR(svn_client_open_ra_session2(&ra_session, uri, NULL,
                                              ctx, pool, pool));
          SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
          SVN_ERR(svn_ra_reparent(ra_session, repos_root, pool));
          repos_relpath = svn_uri_skip_ancestor(repos_root, uri, pool);

          /* Make a new relpaths list for this repository, and add
             this URI's relpath to it. */
          target_uris = apr_array_make(pool, 1, sizeof(const char *));
          APR_ARRAY_PUSH(target_uris, const char *) = apr_pstrdup(pool, uri);

          /* Build our repos_deletables_t item and stash it in the
             hash. */
          repos_deletables = apr_pcalloc(pool, sizeof(*repos_deletables));
          repos_deletables->ra_session = ra_session;
          repos_deletables->target_uris = target_uris;
          svn_hash_sets(deletables, repos_root, repos_deletables);
        }

      /* If we get here, we should have been able to calculate a
         repos_relpath for this URI.  Let's make sure.  (We return an
         RA error code otherwise for 1.6 compatibility.)  */
      if (!repos_relpath || !*repos_relpath)
        return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                                 _("URL '%s' not within a repository"), uri);

      /* Now, test to see if the thing actually exists in HEAD. */
      SVN_ERR(svn_ra_check_path(repos_deletables->ra_session, repos_relpath,
                                SVN_INVALID_REVNUM, &kind, pool));
      if (kind == svn_node_none)
        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                                 _("URL '%s' does not exist"), uri);
    }

  /* Now we iterate over the DELETABLES hash, issuing a commit for
     each repository with its associated collected targets. */
  iterpool = svn_pool_create(pool);
  for (hi = apr_hash_first(pool, deletables); hi; hi = apr_hash_next(hi))
    {
      struct repos_deletables_t *repos_deletables = apr_hash_this_val(hi);
      const char *base_uri;
      apr_array_header_t *target_relpaths;

      svn_pool_clear(iterpool);

      /* We want to anchor the commit on the longest common path
         across the targets for this one repository.  If, however, one
         of our targets is that longest common path, we need instead
         anchor the commit on that path's immediate parent.  Because
         we're asking svn_uri_condense_targets() to remove
         redundancies, this situation should be detectable by their
         being returned either a) only a single, empty-path, target
         relpath, or b) no target relpaths at all.  */
      SVN_ERR(svn_uri_condense_targets(&base_uri, &target_relpaths,
                                       repos_deletables->target_uris,
                                       TRUE, iterpool, iterpool));
      SVN_ERR_ASSERT(!svn_path_is_empty(base_uri));
      if (target_relpaths->nelts == 0)
        {
          const char *target_relpath;

          svn_uri_split(&base_uri, &target_relpath, base_uri, iterpool);
          APR_ARRAY_PUSH(target_relpaths, const char *) = target_relpath;
        }
      else if ((target_relpaths->nelts == 1)
               && (svn_path_is_empty(APR_ARRAY_IDX(target_relpaths, 0,
                                                   const char *))))
        {
          const char *target_relpath;

          svn_uri_split(&base_uri, &target_relpath, base_uri, iterpool);
          APR_ARRAY_IDX(target_relpaths, 0, const char *) = target_relpath;
        }

      SVN_ERR(svn_ra_reparent(repos_deletables->ra_session, base_uri, pool));
      SVN_ERR(single_repos_delete(repos_deletables->ra_session, base_uri,
                                  target_relpaths,
                                  revprop_table, commit_callback,
                                  commit_baton, ctx, iterpool));
    }
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__wc_delete(const char *local_abspath,
                      svn_boolean_t force,
                      svn_boolean_t dry_run,
                      svn_boolean_t keep_local,
                      svn_wc_notify_func2_t notify_func,
                      void *notify_baton,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
{
  svn_boolean_t target_missing = FALSE;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

  SVN_ERR(check_external(local_abspath, ctx, pool));

  if (!force && !keep_local)
    /* Verify that there are no "awkward" files */
    SVN_ERR(can_delete_node(&target_missing, local_abspath, ctx, pool));

  if (!dry_run)
    /* Mark the entry for commit deletion and perform wc deletion */
    return svn_error_trace(svn_wc_delete4(ctx->wc_ctx, local_abspath,
                                          keep_local || target_missing
                                                            /*keep_local */,
                                          TRUE /* delete_unversioned */,
                                          ctx->cancel_func, ctx->cancel_baton,
                                          notify_func, notify_baton, pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__wc_delete_many(const apr_array_header_t *targets,
                           svn_boolean_t force,
                           svn_boolean_t dry_run,
                           svn_boolean_t keep_local,
                           svn_wc_notify_func2_t notify_func,
                           void *notify_baton,
                           svn_client_ctx_t *ctx,
                           apr_pool_t *pool)
{
  int i;
  svn_boolean_t has_non_missing = FALSE;

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

      SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

      SVN_ERR(check_external(local_abspath, ctx, pool));

      if (!force && !keep_local)
        {
          svn_boolean_t missing;
          /* Verify that there are no "awkward" files */

          SVN_ERR(can_delete_node(&missing, local_abspath, ctx, pool));

          if (! missing)
            has_non_missing = TRUE;
        }
      else
        has_non_missing = TRUE;
    }

  if (!dry_run)
    {
      /* Mark the entry for commit deletion and perform wc deletion */

      /* If none of the targets exists, pass keep local TRUE, to avoid
         deleting case-different files. Detecting this in the generic case
         from the delete code is expensive */
      return svn_error_trace(svn_wc__delete_many(ctx->wc_ctx, targets,
                                                 keep_local || !has_non_missing,
                                                 TRUE /* delete_unversioned_target */,
                                                 ctx->cancel_func,
                                                 ctx->cancel_baton,
                                                 notify_func, notify_baton,
                                                 pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_delete4(const apr_array_header_t *paths,
                   svn_boolean_t force,
                   svn_boolean_t keep_local,
                   const apr_hash_t *revprop_table,
                   svn_commit_callback2_t commit_callback,
                   void *commit_baton,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
{
  svn_boolean_t is_url;

  if (! paths->nelts)
    return SVN_NO_ERROR;

  SVN_ERR(svn_client__assert_homogeneous_target_type(paths));
  is_url = svn_path_is_url(APR_ARRAY_IDX(paths, 0, const char *));

  if (is_url)
    {
      SVN_ERR(delete_urls_multi_repos(paths, revprop_table, commit_callback,
                                      commit_baton, ctx, pool));
    }
  else
    {
      const char *local_abspath;
      apr_hash_t *wcroots;
      apr_hash_index_t *hi;
      int i;
      int j;
      apr_pool_t *iterpool;
      svn_boolean_t is_new_target;

      /* Build a map of wcroots and targets within them. */
      wcroots = apr_hash_make(pool);
      iterpool = svn_pool_create(pool);
      for (i = 0; i < paths->nelts; i++)
        {
          const char *wcroot_abspath;
          apr_array_header_t *targets;

          svn_pool_clear(iterpool);

          /* See if the user wants us to stop. */
          if (ctx->cancel_func)
            SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

          SVN_ERR(svn_dirent_get_absolute(&local_abspath,
                                          APR_ARRAY_IDX(paths, i,
                                                        const char *),
                                          pool));
          SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx,
                                     local_abspath, pool, iterpool));
          targets = svn_hash_gets(wcroots, wcroot_abspath);
          if (targets == NULL)
            {
              targets = apr_array_make(pool, 1, sizeof(const char *));
              svn_hash_sets(wcroots, wcroot_abspath, targets);
             }

          /* Make sure targets are unique. */
          is_new_target = TRUE;
          for (j = 0; j < targets->nelts; j++)
            {
              if (strcmp(APR_ARRAY_IDX(targets, j, const char *),
                         local_abspath) == 0)
                {
                  is_new_target = FALSE;
                  break;
                }
            }

          if (is_new_target)
            APR_ARRAY_PUSH(targets, const char *) = local_abspath;
        }

      /* Delete the targets from each working copy in turn. */
      for (hi = apr_hash_first(pool, wcroots); hi; hi = apr_hash_next(hi))
        {
          const char *root_abspath;
          const apr_array_header_t *targets = apr_hash_this_val(hi);

          svn_pool_clear(iterpool);

          SVN_ERR(svn_dirent_condense_targets(&root_abspath, NULL, targets,
                                              FALSE, iterpool, iterpool));

          SVN_WC__CALL_WITH_WRITE_LOCK(
            svn_client__wc_delete_many(targets, force, FALSE, keep_local,
                                       ctx->notify_func2, ctx->notify_baton2,
                                       ctx, iterpool),
            ctx->wc_ctx, root_abspath, TRUE /* lock_anchor */,
            iterpool);
        }
      svn_pool_destroy(iterpool);
    }

  return SVN_NO_ERROR;
}
