/*
 * info.c:  return system-generated metadata about paths or URLs.
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */

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



#include "client.h"
#include "svn_client.h"
#include "svn_dirent_uri.h"
#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_sorts.h"

#include "svn_wc.h"

#include "svn_private_config.h"
#include "private/svn_fspath.h"
#include "private/svn_sorts_private.h"
#include "private/svn_wc_private.h"


svn_client_info2_t *
svn_client_info2_dup(const svn_client_info2_t *info,
                     apr_pool_t *pool)
{
  svn_client_info2_t *new_info = apr_pmemdup(pool, info, sizeof(*new_info));

  if (new_info->URL)
    new_info->URL = apr_pstrdup(pool, info->URL);
  if (new_info->repos_root_URL)
    new_info->repos_root_URL = apr_pstrdup(pool, info->repos_root_URL);
  if (new_info->repos_UUID)
    new_info->repos_UUID = apr_pstrdup(pool, info->repos_UUID);
  if (info->last_changed_author)
    new_info->last_changed_author = apr_pstrdup(pool, info->last_changed_author);
  if (new_info->lock)
    new_info->lock = svn_lock_dup(info->lock, pool);
  if (new_info->wc_info)
    new_info->wc_info = svn_wc_info_dup(info->wc_info, pool);
  return new_info;
}

/* Handle externals for svn_client_info4() */

static svn_error_t *
do_external_info(apr_hash_t *external_map,
                 svn_depth_t depth,
                 svn_boolean_t fetch_excluded,
                 svn_boolean_t fetch_actual_only,
                 const apr_array_header_t *changelists,
                 svn_client_info_receiver2_t receiver,
                 void *receiver_baton,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_array_header_t *externals;
  int i;

  externals = svn_sort__hash(external_map, svn_sort_compare_items_lexically,
                             scratch_pool);

  /* Loop over the hash of new values (we don't care about the old
     ones).  This is a mapping of versioned directories to property
     values. */
  for (i = 0; i < externals->nelts; i++)
    {
      svn_node_kind_t external_kind;
      svn_sort__item_t item = APR_ARRAY_IDX(externals, i, svn_sort__item_t);
      const char *local_abspath = item.key;
      const char *defining_abspath = item.value;
      svn_opt_revision_t opt_rev;
      svn_node_kind_t kind;

      svn_pool_clear(iterpool);

      /* Obtain information on the expected external. */
      SVN_ERR(svn_wc__read_external_info(&external_kind, NULL, NULL, NULL,
                                         &opt_rev.value.number,
                                         ctx->wc_ctx, defining_abspath,
                                         local_abspath, FALSE,
                                         iterpool, iterpool));

      if (external_kind != svn_node_dir)
        continue;

      SVN_ERR(svn_io_check_path(local_abspath, &kind, iterpool));
      if (kind != svn_node_dir)
        continue;

      /* Tell the client we're starting an external info. */
      if (ctx->notify_func2)
        ctx->notify_func2(
               ctx->notify_baton2,
               svn_wc_create_notify(local_abspath,
                                    svn_wc_notify_info_external,
                                    iterpool), iterpool);

      SVN_ERR(svn_client_info4(local_abspath,
                               NULL /* peg_revision */,
                               NULL /* revision */,
                               depth,
                               fetch_excluded,
                               fetch_actual_only,
                               TRUE /* include_externals */,
                               changelists,
                               receiver, receiver_baton,
                               ctx, iterpool));
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Set *INFO to a new info struct built from DIRENT
   and (possibly NULL) svn_lock_t LOCK, all allocated in POOL.
   Pointer fields are copied by reference, not dup'd. */
static svn_error_t *
build_info_from_dirent(svn_client_info2_t **info,
                       const svn_dirent_t *dirent,
                       svn_lock_t *lock,
                       const svn_client__pathrev_t *pathrev,
                       apr_pool_t *pool)
{
  svn_client_info2_t *tmpinfo = apr_pcalloc(pool, sizeof(*tmpinfo));

  tmpinfo->URL                  = pathrev->url;
  tmpinfo->rev                  = pathrev->rev;
  tmpinfo->kind                 = dirent->kind;
  tmpinfo->repos_UUID           = pathrev->repos_uuid;
  tmpinfo->repos_root_URL       = pathrev->repos_root_url;
  tmpinfo->last_changed_rev     = dirent->created_rev;
  tmpinfo->last_changed_date    = dirent->time;
  tmpinfo->last_changed_author  = dirent->last_author;
  tmpinfo->lock                 = lock;
  tmpinfo->size                 = dirent->size;

  tmpinfo->wc_info              = NULL;

  *info = tmpinfo;
  return SVN_NO_ERROR;
}


/* The dirent fields we care about for our calls to svn_ra_get_dir2. */
#define DIRENT_FIELDS (SVN_DIRENT_KIND        | \
                       SVN_DIRENT_CREATED_REV | \
                       SVN_DIRENT_TIME        | \
                       SVN_DIRENT_LAST_AUTHOR | \
                       SVN_DIRENT_SIZE)


/* Helper func for recursively fetching svn_dirent_t's from a remote
   directory and pushing them at an info-receiver callback.

   DEPTH is the depth starting at DIR, even though RECEIVER is never
   invoked on DIR: if DEPTH is svn_depth_immediates, then invoke
   RECEIVER on all children of DIR, but none of their children; if
   svn_depth_files, then invoke RECEIVER on file children of DIR but
   not on subdirectories; if svn_depth_infinity, recurse fully.
   DIR is a relpath, relative to the root of RA_SESSION.
*/
static svn_error_t *
push_dir_info(svn_ra_session_t *ra_session,
              const svn_client__pathrev_t *pathrev,
              const char *dir,
              svn_client_info_receiver2_t receiver,
              void *receiver_baton,
              svn_depth_t depth,
              svn_client_ctx_t *ctx,
              apr_hash_t *locks,
              apr_pool_t *pool)
{
  apr_hash_t *tmpdirents;
  apr_hash_index_t *hi;
  apr_pool_t *subpool = svn_pool_create(pool);

  SVN_ERR(svn_ra_get_dir2(ra_session, &tmpdirents, NULL, NULL,
                          dir, pathrev->rev, DIRENT_FIELDS, pool));

  for (hi = apr_hash_first(pool, tmpdirents); hi; hi = apr_hash_next(hi))
    {
      const char *path, *fs_path;
      svn_lock_t *lock;
      svn_client_info2_t *info;
      const char *name = apr_hash_this_key(hi);
      svn_dirent_t *the_ent = apr_hash_this_val(hi);
      svn_client__pathrev_t *child_pathrev;

      svn_pool_clear(subpool);

      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

      path = svn_relpath_join(dir, name, subpool);
      child_pathrev = svn_client__pathrev_join_relpath(pathrev, name, subpool);
      fs_path = svn_client__pathrev_fspath(child_pathrev, subpool);

      lock = svn_hash_gets(locks, fs_path);

      SVN_ERR(build_info_from_dirent(&info, the_ent, lock, child_pathrev,
                                     subpool));

      if (depth >= svn_depth_immediates
          || (depth == svn_depth_files && the_ent->kind == svn_node_file))
        {
          SVN_ERR(receiver(receiver_baton, path, info, subpool));
        }

      if (depth == svn_depth_infinity && the_ent->kind == svn_node_dir)
        {
          SVN_ERR(push_dir_info(ra_session, child_pathrev, path,
                                receiver, receiver_baton,
                                depth, ctx, locks, subpool));
        }
    }

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}


/* Set *SAME_P to TRUE if URL exists in the head of the repository and
   refers to the same resource as it does in REV, using POOL for
   temporary allocations.  RA_SESSION is an open RA session for URL.  */
static svn_error_t *
same_resource_in_head(svn_boolean_t *same_p,
                      const char *url,
                      svn_revnum_t rev,
                      svn_ra_session_t *ra_session,
                      svn_client_ctx_t *ctx,
                      apr_pool_t *pool)
{
  svn_error_t *err;
  svn_opt_revision_t operative_rev, peg_rev;
  const char *head_url;

  peg_rev.kind = svn_opt_revision_head;
  operative_rev.kind = svn_opt_revision_number;
  operative_rev.value.number = rev;

  err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
                                    ra_session,
                                    url, &peg_rev,
                                    &operative_rev, NULL,
                                    ctx, pool);
  if (err &&
      ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||
       (err->apr_err == SVN_ERR_FS_NOT_DIRECTORY) ||
       (err->apr_err == SVN_ERR_FS_NOT_FOUND)))
    {
      svn_error_clear(err);
      *same_p = FALSE;
      return SVN_NO_ERROR;
    }
  else
    SVN_ERR(err);

  /* ### Currently, the URLs should always be equal, since we can't
     ### walk forwards in history. */
  *same_p = (strcmp(url, head_url) == 0);

  return SVN_NO_ERROR;
}

/* A baton for wc_info_receiver(), containing the wrapped receiver. */
typedef struct wc_info_receiver_baton_t
{
  svn_client_info_receiver2_t client_receiver_func;
  void *client_receiver_baton;
} wc_info_receiver_baton_t;

/* A receiver for WC info, implementing svn_client_info_receiver2_t.
 * Convert the WC info to client info and pass it to the client info
 * receiver (BATON->client_receiver_func with BATON->client_receiver_baton). */
static svn_error_t *
wc_info_receiver(void *baton,
                 const char *abspath_or_url,
                 const svn_wc__info2_t *wc_info,
                 apr_pool_t *scratch_pool)
{
  wc_info_receiver_baton_t *b = baton;
  svn_client_info2_t client_info;

  /* Make a shallow copy in CLIENT_INFO of the contents of WC_INFO. */
  client_info.repos_root_URL = wc_info->repos_root_URL;
  client_info.repos_UUID = wc_info->repos_UUID;
  client_info.rev = wc_info->rev;
  client_info.URL = wc_info->URL;

  client_info.kind = wc_info->kind;
  client_info.size = wc_info->size;
  client_info.last_changed_rev = wc_info->last_changed_rev;
  client_info.last_changed_date = wc_info->last_changed_date;
  client_info.last_changed_author = wc_info->last_changed_author;

  client_info.lock = wc_info->lock;

  client_info.wc_info = wc_info->wc_info;

  return b->client_receiver_func(b->client_receiver_baton,
                                 abspath_or_url, &client_info, scratch_pool);
}

svn_error_t *
svn_client_info4(const char *abspath_or_url,
                 const svn_opt_revision_t *peg_revision,
                 const svn_opt_revision_t *revision,
                 svn_depth_t depth,
                 svn_boolean_t fetch_excluded,
                 svn_boolean_t fetch_actual_only,
                 svn_boolean_t include_externals,
                 const apr_array_header_t *changelists,
                 svn_client_info_receiver2_t receiver,
                 void *receiver_baton,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
{
  svn_ra_session_t *ra_session;
  svn_client__pathrev_t *pathrev;
  svn_lock_t *lock;
  svn_boolean_t related;
  const char *base_name;
  svn_dirent_t *the_ent;
  svn_client_info2_t *info;
  svn_error_t *err;

  if (depth == svn_depth_unknown)
    depth = svn_depth_empty;

  if ((revision == NULL
       || revision->kind == svn_opt_revision_unspecified)
      && (peg_revision == NULL
          || peg_revision->kind == svn_opt_revision_unspecified))
    {
      /* Do all digging in the working copy. */
      wc_info_receiver_baton_t b;

      b.client_receiver_func = receiver;
      b.client_receiver_baton = receiver_baton;
      SVN_ERR(svn_wc__get_info(ctx->wc_ctx, abspath_or_url, depth,
                               fetch_excluded, fetch_actual_only, changelists,
                               wc_info_receiver, &b,
                               ctx->cancel_func, ctx->cancel_baton, pool));

      if (include_externals && SVN_DEPTH_IS_RECURSIVE(depth))
        {
          apr_hash_t *external_map;

          SVN_ERR(svn_wc__externals_defined_below(&external_map,
                                                  ctx->wc_ctx, abspath_or_url,
                                                  pool, pool));

          SVN_ERR(do_external_info(external_map,
                                   depth, fetch_excluded, fetch_actual_only,
                                   changelists,
                                   receiver, receiver_baton, ctx, pool));
        }

      return SVN_NO_ERROR;
    }

  /* Go repository digging instead. */

  /* Trace rename history (starting at path_or_url@peg_revision) and
     return RA session to the possibly-renamed URL as it exists in REVISION.
     The ra_session returned will be anchored on this "final" URL. */
  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &pathrev,
                                            abspath_or_url, NULL, peg_revision,
                                            revision, ctx, pool));
  base_name = svn_uri_basename(pathrev->url, pool);

  /* Get the dirent for the URL itself. */
  SVN_ERR(svn_ra_stat(ra_session, "", pathrev->rev, &the_ent, pool));

  if (! the_ent)
    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                             _("URL '%s' non-existent in revision %ld"),
                             pathrev->url, pathrev->rev);

  /* Check if the URL exists in HEAD and refers to the same resource.
     In this case, we check the repository for a lock on this URL.

     ### There is a possible race here, since HEAD might have changed since
     ### we checked it.  A solution to this problem could be to do the below
     ### check in a loop which only terminates if the HEAD revision is the same
     ### before and after this check.  That could, however, lead to a
     ### starvation situation instead.  */
  SVN_ERR(same_resource_in_head(&related, pathrev->url, pathrev->rev,
                                ra_session, ctx, pool));
  if (related)
    {
      err = svn_ra_get_lock(ra_session, &lock, "", pool);

      /* An old mod_dav_svn will always work; there's nothing wrong with
         doing a PROPFIND for a property named "DAV:supportedlock". But
         an old svnserve will error. */
      if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
        {
          svn_error_clear(err);
          lock = NULL;
        }
      else if (err)
        return svn_error_trace(err);
    }
  else
    lock = NULL;

  /* Push the URL's dirent (and lock) at the callback.*/
  SVN_ERR(build_info_from_dirent(&info, the_ent, lock, pathrev, pool));
  SVN_ERR(receiver(receiver_baton, base_name, info, pool));

  /* Possibly recurse, using the original RA session. */
  if (depth > svn_depth_empty && (the_ent->kind == svn_node_dir))
    {
      apr_hash_t *locks;

      if (peg_revision->kind == svn_opt_revision_head)
        {
          err = svn_ra_get_locks2(ra_session, &locks, "", depth,
                                  pool);

          /* Catch specific errors thrown by old mod_dav_svn or svnserve. */
          if (err && err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)
            {
              svn_error_clear(err);
              locks = apr_hash_make(pool); /* use an empty hash */
            }
          else if (err)
            return svn_error_trace(err);
        }
      else
        locks = apr_hash_make(pool); /* use an empty hash */

      SVN_ERR(push_dir_info(ra_session, pathrev, "",
                            receiver, receiver_baton,
                            depth, ctx, locks, pool));
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client_get_wc_root(const char **wcroot_abspath,
                       const char *local_abspath,
                       svn_client_ctx_t *ctx,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  return svn_wc__get_wcroot(wcroot_abspath, ctx->wc_ctx, local_abspath,
                            result_pool, scratch_pool);
}


/* NOTE: This function was requested by the TortoiseSVN project.  See
   issue #3927. */
svn_error_t *
svn_client_min_max_revisions(svn_revnum_t *min_revision,
                             svn_revnum_t *max_revision,
                             const char *local_abspath,
                             svn_boolean_t committed,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *scratch_pool)
{
  return svn_wc__min_max_revisions(min_revision, max_revision, ctx->wc_ctx,
                                   local_abspath, committed, scratch_pool);
}
