/*
 * util.c:  Repository access utility routines.
 *
 * ====================================================================
 *    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_pools.h>
#include <apr_network_io.h>

#include "svn_types.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_ra.h"

#include "svn_private_config.h"
#include "private/svn_ra_private.h"

static const char *
get_path(const char *path_or_url,
         svn_ra_session_t *ra_session,
         apr_pool_t *pool)
{
  if (path_or_url == NULL)
    {
      svn_error_t *err = svn_ra_get_session_url(ra_session, &path_or_url,
                                                pool);
      if (err)
        {
          /* The SVN_ERR_UNSUPPORTED_FEATURE error in the caller is more
             important, so dummy up the session's URL and chuck this error. */
          svn_error_clear(err);
          return _("<repository>");
        }
    }
  return path_or_url;
}

svn_error_t *
svn_ra__assert_mergeinfo_capable_server(svn_ra_session_t *ra_session,
                                        const char *path_or_url,
                                        apr_pool_t *pool)
{
  svn_boolean_t mergeinfo_capable;
  SVN_ERR(svn_ra_has_capability(ra_session, &mergeinfo_capable,
                                SVN_RA_CAPABILITY_MERGEINFO, pool));
  if (! mergeinfo_capable)
    {
      path_or_url = get_path(path_or_url, ra_session, pool);
      return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                               _("Retrieval of mergeinfo unsupported by '%s'"),
                               svn_path_is_url(path_or_url)
                                  ? path_or_url
                                  : svn_dirent_local_style(path_or_url, pool));
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_ra__assert_capable_server(svn_ra_session_t *ra_session,
                              const char *capability,
                              const char *path_or_url,
                              apr_pool_t *pool)
{
  if (!strcmp(capability, SVN_RA_CAPABILITY_MERGEINFO))
    return svn_ra__assert_mergeinfo_capable_server(ra_session, path_or_url,
                                                   pool);

  else
    {
      svn_boolean_t has;
      SVN_ERR(svn_ra_has_capability(ra_session, &has, capability, pool));
      if (! has)
        {
          path_or_url = get_path(path_or_url, ra_session, pool);
          return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                 _("The '%s' feature is not supported by '%s'"),
                                 capability,
                                 svn_path_is_url(path_or_url)
                                    ? path_or_url
                                    : svn_dirent_local_style(path_or_url,
                                                             pool));
        }
    }
  return SVN_NO_ERROR;
}

/* Does ERR mean "the current value of the revprop isn't equal to
   the *OLD_VALUE_P you gave me"?
 */
static svn_boolean_t is_atomicity_error(svn_error_t *err)
{
  return svn_error_find_cause(err, SVN_ERR_FS_PROP_BASEVALUE_MISMATCH) != NULL;
}

svn_error_t *
svn_ra__release_operational_lock(svn_ra_session_t *session,
                                 const char *lock_revprop_name,
                                 const svn_string_t *mylocktoken,
                                 apr_pool_t *scratch_pool)
{
  svn_string_t *reposlocktoken;
  svn_boolean_t be_atomic;

  SVN_ERR(svn_ra_has_capability(session, &be_atomic,
                                SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
                                scratch_pool));
  SVN_ERR(svn_ra_rev_prop(session, 0, lock_revprop_name,
                          &reposlocktoken, scratch_pool));
  if (reposlocktoken && svn_string_compare(reposlocktoken, mylocktoken))
    {
      svn_error_t *err;

      err = svn_ra_change_rev_prop2(session, 0, lock_revprop_name,
                                    be_atomic ? &mylocktoken : NULL, NULL,
                                    scratch_pool);
      if (is_atomicity_error(err))
        {
          return svn_error_createf(err->apr_err, err,
                                   _("Lock was stolen by '%s'; unable to "
                                     "remove it"), reposlocktoken->data);
        }
      else
        SVN_ERR(err);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_ra__get_operational_lock(const svn_string_t **lock_string_p,
                             const svn_string_t **stolen_lock_p,
                             svn_ra_session_t *session,
                             const char *lock_revprop_name,
                             svn_boolean_t steal_lock,
                             int num_retries,
                             svn_ra__lock_retry_func_t retry_func,
                             void *retry_baton,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             apr_pool_t *pool)
{
  char hostname_str[APRMAXHOSTLEN + 1] = { 0 };
  svn_string_t *mylocktoken, *reposlocktoken;
  apr_status_t apr_err;
  svn_boolean_t be_atomic;
  apr_pool_t *subpool;
  int i;

  *lock_string_p = NULL;
  if (stolen_lock_p)
    *stolen_lock_p = NULL;

  SVN_ERR(svn_ra_has_capability(session, &be_atomic,
                                SVN_RA_CAPABILITY_ATOMIC_REVPROPS, pool));

  /* We build a lock token from the local hostname and a UUID.  */
  apr_err = apr_gethostname(hostname_str, sizeof(hostname_str), pool);
  if (apr_err)
    return svn_error_wrap_apr(apr_err,
                              _("Unable to determine local hostname"));
  mylocktoken = svn_string_createf(pool, "%s:%s", hostname_str,
                                   svn_uuid_generate(pool));

  /* Ye Olde Retry Loope */
  subpool = svn_pool_create(pool);

  for (i = 0; i < num_retries; ++i)
    {
      svn_error_t *err;
      const svn_string_t *unset = NULL;

      svn_pool_clear(subpool);

      /* Check for cancellation.  If we're cancelled, don't leave a
         stray lock behind!  */
      if (cancel_func)
        {
          err = cancel_func(cancel_baton);
          if (err && err->apr_err == SVN_ERR_CANCELLED)
            return svn_error_compose_create(
                       svn_ra__release_operational_lock(session,
                                                        lock_revprop_name,
                                                        mylocktoken,
                                                        subpool),
                       err);
          SVN_ERR(err);
        }

      /* Ask the repository for the value of the LOCK_REVPROP_NAME. */
      SVN_ERR(svn_ra_rev_prop(session, 0, lock_revprop_name,
                              &reposlocktoken, subpool));

      /* Did we get a value from the repository?  We'll check to see
         if it matches our token.  If so, we call it success.  If not
         and we're told to steal locks, we remember the existing lock
         token and fall through to the locking code; otherwise, we
         sleep and retry. */
      if (reposlocktoken)
        {
          if (svn_string_compare(reposlocktoken, mylocktoken))
            {
              *lock_string_p = mylocktoken;
              return SVN_NO_ERROR;
            }
          else if (! steal_lock)
            {
              if (retry_func)
                SVN_ERR(retry_func(retry_baton, reposlocktoken, subpool));
              apr_sleep(apr_time_from_sec(1));
              continue;
            }
          else
            {
              if (stolen_lock_p)
                *stolen_lock_p = svn_string_dup(reposlocktoken, pool);
              unset = reposlocktoken;
            }
        }

      /* No lock value in the repository, or we plan to steal it?
         Well, if we've got a spare iteration, we'll try to set the
         lock.  (We use the spare iteration to verify that we still
         have the lock after setting it.) */
      if (i < num_retries - 1)
        {
          /* Except in the very last iteration, try to set the lock. */
          err = svn_ra_change_rev_prop2(session, 0, lock_revprop_name,
                                        be_atomic ? &unset : NULL,
                                        mylocktoken, subpool);

          if (be_atomic && err && is_atomicity_error(err))
            {
              /* Someone else has the lock.  No problem, we'll loop again. */
              svn_error_clear(err);
            }
          else if (be_atomic && err == SVN_NO_ERROR)
            {
              /* Yay!  We have the lock!  However, for compatibility
                 with concurrent processes that don't support
                 atomicity, loop anyway to double-check that they
                 haven't overwritten our lock.
              */
              continue;
            }
          else
            {
              /* We have a genuine error, or aren't atomic and need
                 to loop.  */
              SVN_ERR(err);
            }
        }
    }

  return svn_error_createf(APR_EINVAL, NULL,
                           _("Couldn't get lock on destination repos "
                             "after %d attempts"), i);
}
