/**
 * @copyright
 * ====================================================================
 *    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.
 * ====================================================================
 * @endcopyright
 */

#include <apr_pools.h>
#include <apr_hash.h>
#include <apr_time.h>

#include "svn_types.h"
#include "svn_string.h"
#include "svn_props.h"
#include "svn_compat.h"

/* This file is a template for a compatibility wrapper for an RA library.
 * It contains an svn_ra_plugin_t and wrappers for all of its functions,
 * implemented in terms of svn_ra__vtable_t functions.  It also contains
 * the implementations of an svn_ra_FOO_init for the FOO RA library.
 *
 * A file in the RA library includes this file, providing the
 * following macros before inclusion:
 *
 * NAME             The library name, e.g. "ra_local".
 * DESCRIPTION      The short library description as a string constant.
 * VTBL             The name of an svn_ra_vtable_t object for the library.
 * INITFUNC         The init function for the library, e.g. svn_ra_local__init.
 * COMPAT_INITFUNC  The compatibility init function, e.g. svn_ra_local_init.
 */

/* Check that all our "arguments" are defined. */
#if ! defined(NAME) || ! defined(DESCRIPTION) || ! defined(VTBL) \
    || ! defined(INITFUNC) || ! defined(COMPAT_INITFUNC)
#error Missing define for RA compatibility wrapper.
#endif


static svn_error_t *compat_open(void **session_baton,
                                const char *repos_URL,
                                const svn_ra_callbacks_t *callbacks,
                                void *callback_baton,
                                apr_hash_t *config,
                                apr_pool_t *pool)
{
  /* Here, we should be calling svn_ra_create_callbacks to initialize
   * the svn_ra_callbacks2_t structure.  However, doing that
   * introduces a circular dependency between libsvn_ra and
   * libsvn_ra_{local,neon,serf,svn}, which include
   * wrapper_template.h.  In turn, circular dependencies break the
   * build on win32 (and possibly other systems).
   *
   * In order to avoid this happening at all, the code of
   * svn_ra_create_callbacks is duplicated here.  This is evil, but
   * the alternative (creating a new ra_util library) would be massive
   * overkill for the time being.  Just be sure to keep the following
   * line and the code of svn_ra_create_callbacks in sync.  */
  apr_pool_t *sesspool = svn_pool_create(pool);
  svn_ra_callbacks2_t *callbacks2 = apr_pcalloc(sesspool,
                                                sizeof(*callbacks2));

  svn_ra_session_t *sess = apr_pcalloc(sesspool, sizeof(*sess));
  const char *session_url;

  sess->vtable = &VTBL;
  sess->pool = sesspool;

  callbacks2->open_tmp_file = callbacks->open_tmp_file;
  callbacks2->auth_baton = callbacks->auth_baton;
  callbacks2->get_wc_prop = callbacks->get_wc_prop;
  callbacks2->set_wc_prop = callbacks->set_wc_prop;
  callbacks2->push_wc_prop = callbacks->push_wc_prop;
  callbacks2->invalidate_wc_props = callbacks->invalidate_wc_props;
  callbacks2->progress_func = NULL;
  callbacks2->progress_baton = NULL;

  SVN_ERR(VTBL.open_session(sess, &session_url, NULL, repos_URL,
                            callbacks2, callback_baton,
                            callbacks ? callbacks->auth_baton : NULL,
                            config, sesspool, sesspool));

  if (strcmp(repos_URL, session_url) != 0)
    {
      svn_pool_destroy(sesspool);
      return svn_error_createf(SVN_ERR_RA_SESSION_URL_MISMATCH, NULL,
                               _("Session URL '%s' does not match requested "
                                 " URL '%s', and redirection was disallowed."),
                               session_url, repos_URL);
    }

  *session_baton = sess;
  return SVN_NO_ERROR;
}

static svn_error_t *compat_get_latest_revnum(void *session_baton,
                                             svn_revnum_t *latest_revnum,
                                             apr_pool_t *pool)
{
  return VTBL.get_latest_revnum(session_baton, latest_revnum, pool);
}

static svn_error_t *compat_get_dated_revision(void *session_baton,
                                              svn_revnum_t *revision,
                                              apr_time_t tm,
                                              apr_pool_t *pool)
{
  return VTBL.get_dated_revision(session_baton, revision, tm, pool);
}

static svn_error_t *compat_change_rev_prop(void *session_baton,
                                           svn_revnum_t rev,
                                           const char *propname,
                                           const svn_string_t *value,
                                           apr_pool_t *pool)
{
  return VTBL.change_rev_prop(session_baton, rev, propname, NULL, value, pool);
}

static svn_error_t *compat_rev_proplist(void *session_baton,
                                        svn_revnum_t rev,
                                        apr_hash_t **props,
                                        apr_pool_t *pool)
{
  return VTBL.rev_proplist(session_baton, rev, props, pool);
}

static svn_error_t *compat_rev_prop(void *session_baton,
                                    svn_revnum_t rev,
                                    const char *propname,
                                    svn_string_t **value,
                                    apr_pool_t *pool)
{
  return VTBL.rev_prop(session_baton, rev, propname, value, pool);
}

static svn_error_t *compat_get_commit_editor(void *session_baton,
                                             const svn_delta_editor_t
                                             **editor,
                                             void **edit_baton,
                                             const char *log_msg,
                                             svn_commit_callback_t callback,
                                             void *callback_baton,
                                             apr_pool_t *pool)
{
  svn_commit_callback2_t callback2;
  void *callback2_baton;
  apr_hash_t *revprop_table = apr_hash_make(pool);

  svn_compat_wrap_commit_callback(&callback2, &callback2_baton,
                                  callback, callback_baton,
                                  pool);
  apr_hash_set(revprop_table, SVN_PROP_REVISION_LOG, APR_HASH_KEY_STRING,
               svn_string_create(log_msg, pool));
  return VTBL.get_commit_editor(session_baton, editor, edit_baton,
                                revprop_table, callback2, callback2_baton,
                                NULL, TRUE, pool);
}

static svn_error_t *compat_get_file(void *session_baton,
                                    const char *path,
                                    svn_revnum_t revision,
                                    svn_stream_t *stream,
                                    svn_revnum_t *fetched_rev,
                                    apr_hash_t **props,
                                    apr_pool_t *pool)
{
  return VTBL.get_file(session_baton, path, revision, stream, fetched_rev,
                       props, pool);
}

static svn_error_t *compat_get_dir(void *session_baton,
                                   const char *path,
                                   svn_revnum_t revision,
                                   apr_hash_t **dirents,
                                   svn_revnum_t *fetched_rev,
                                   apr_hash_t **props,
                                   apr_pool_t *pool)
{
  return VTBL.get_dir(session_baton, dirents, fetched_rev, props,
                      path, revision, SVN_DIRENT_ALL, pool);
}

/** Reporter compat code. **/

struct compat_report_baton {
  const svn_ra_reporter3_t *reporter;
  void *baton;
};

static svn_error_t *compat_set_path(void *report_baton,
                                    const char *path,
                                    svn_revnum_t revision,
                                    svn_boolean_t start_empty,
                                    apr_pool_t *pool)
{
  struct compat_report_baton *crb = report_baton;

  return crb->reporter->set_path(crb->baton, path, revision,
                                 svn_depth_infinity, start_empty,
                                 NULL, pool);
}

static svn_error_t *compat_delete_path(void *report_baton,
                                       const char *path,
                                       apr_pool_t *pool)
{
  struct compat_report_baton *crb = report_baton;

  return crb->reporter->delete_path(crb->baton, path, pool);
}

static svn_error_t *compat_link_path(void *report_baton,
                                     const char *path,
                                     const char *url,
                                     svn_revnum_t revision,
                                     svn_boolean_t start_empty,
                                     apr_pool_t *pool)
{
  struct compat_report_baton *crb = report_baton;

  return crb->reporter->link_path(crb->baton, path, url, revision,
                                  svn_depth_infinity, start_empty,
                                  NULL, pool);
}

static svn_error_t *compat_finish_report(void *report_baton,
                                         apr_pool_t *pool)
{
  struct compat_report_baton *crb = report_baton;

  return crb->reporter->finish_report(crb->baton, pool);
}

static svn_error_t *compat_abort_report(void *report_baton,
                                        apr_pool_t *pool)
{
  struct compat_report_baton *crb = report_baton;

  return crb->reporter->abort_report(crb->baton, pool);
}

static const svn_ra_reporter_t compat_reporter = {
  compat_set_path,
  compat_delete_path,
  compat_link_path,
  compat_finish_report,
  compat_abort_report
};

static void compat_wrap_reporter(const svn_ra_reporter_t **reporter,
                                 void **baton,
                                 const svn_ra_reporter3_t *wrapped,
                                 void *wrapped_baton,
                                 apr_pool_t *pool)
{
  struct compat_report_baton *crb = apr_palloc(pool, sizeof(*crb));
  crb->reporter = wrapped;
  crb->baton = wrapped_baton;

  *reporter = &compat_reporter;
  *baton = crb;
}

static svn_error_t *compat_do_update(void *session_baton,
                                     const svn_ra_reporter_t **reporter,
                                     void **report_baton,
                                     svn_revnum_t revision_to_update_to,
                                     const char *update_target,
                                     svn_boolean_t recurse,
                                     const svn_delta_editor_t *editor,
                                     void *update_baton,
                                     apr_pool_t *pool)
{
  const svn_ra_reporter3_t *reporter3;
  void *baton3;
  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_FILES(recurse);

  SVN_ERR(VTBL.do_update(session_baton, &reporter3, &baton3,
                         revision_to_update_to, update_target, depth,
                         FALSE /* send_copyfrom_args */,
                         FALSE /* ignore_ancestry */,
                         editor, update_baton,
                         pool, pool));
  compat_wrap_reporter(reporter, report_baton, reporter3, baton3, pool);

  return SVN_NO_ERROR;
}

static svn_error_t *compat_do_switch(void *session_baton,
                                     const svn_ra_reporter_t **reporter,
                                     void **report_baton,
                                     svn_revnum_t revision_to_switch_to,
                                     const char *switch_target,
                                     svn_boolean_t recurse,
                                     const char *switch_url,
                                     const svn_delta_editor_t *editor,
                                     void *switch_baton,
                                     apr_pool_t *pool)
{
  const svn_ra_reporter3_t *reporter3;
  void *baton3;
  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_FILES(recurse);

  SVN_ERR(VTBL.do_switch(session_baton, &reporter3, &baton3,
                         revision_to_switch_to, switch_target, depth,
                         switch_url,
                         FALSE /* send_copyfrom_args */,
                         TRUE /* ignore_ancestry */,
                         editor, switch_baton,
                         pool /* result_pool */, pool /* scratch_pool */));

  compat_wrap_reporter(reporter, report_baton, reporter3, baton3, pool);

  return SVN_NO_ERROR;
}

static svn_error_t *compat_do_status(void *session_baton,
                                     const svn_ra_reporter_t **reporter,
                                     void **report_baton,
                                     const char *status_target,
                                     svn_revnum_t revision,
                                     svn_boolean_t recurse,
                                     const svn_delta_editor_t *editor,
                                     void *status_baton,
                                     apr_pool_t *pool)
{
  const svn_ra_reporter3_t *reporter3;
  void *baton3;
  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_IMMEDIATES(recurse);

  SVN_ERR(VTBL.do_status(session_baton, &reporter3, &baton3, status_target,
                         revision, depth, editor, status_baton, pool));

  compat_wrap_reporter(reporter, report_baton, reporter3, baton3, pool);

  return SVN_NO_ERROR;
}

static svn_error_t *compat_do_diff(void *session_baton,
                                   const svn_ra_reporter_t **reporter,
                                   void **report_baton,
                                   svn_revnum_t revision,
                                   const char *diff_target,
                                   svn_boolean_t recurse,
                                   svn_boolean_t ignore_ancestry,
                                   const char *versus_url,
                                   const svn_delta_editor_t *diff_editor,
                                   void *diff_baton,
                                   apr_pool_t *pool)
{
  const svn_ra_reporter3_t *reporter3;
  void *baton3;
  svn_depth_t depth = SVN_DEPTH_INFINITY_OR_FILES(recurse);

  SVN_ERR(VTBL.do_diff(session_baton, &reporter3, &baton3, revision,
                       diff_target, depth, ignore_ancestry, TRUE,
                       versus_url, diff_editor, diff_baton, pool));

  compat_wrap_reporter(reporter, report_baton, reporter3, baton3, pool);

  return SVN_NO_ERROR;
}

static svn_error_t *compat_get_log(void *session_baton,
                                   const apr_array_header_t *paths,
                                   svn_revnum_t start,
                                   svn_revnum_t end,
                                   svn_boolean_t discover_changed_paths,
                                   svn_boolean_t strict_node_history,
                                   svn_log_message_receiver_t receiver,
                                   void *receiver_baton,
                                   apr_pool_t *pool)
{
  svn_log_entry_receiver_t receiver2;
  void *receiver2_baton;

  svn_compat_wrap_log_receiver(&receiver2, &receiver2_baton,
                               receiver, receiver_baton,
                               pool);

  return VTBL.get_log(session_baton, paths, start, end, 0, /* limit */
                      discover_changed_paths, strict_node_history,
                      FALSE, /* include_merged_revisions */
                      svn_compat_log_revprops_in(pool), /* revprops */
                      receiver2, receiver2_baton, pool);
}

static svn_error_t *compat_check_path(void *session_baton,
                                      const char *path,
                                      svn_revnum_t revision,
                                      svn_node_kind_t *kind,
                                      apr_pool_t *pool)
{
  return VTBL.check_path(session_baton, path, revision, kind, pool);
}

static svn_error_t *compat_get_uuid(void *session_baton,
                                    const char **uuid,
                                    apr_pool_t *pool)
{
  return VTBL.get_uuid(session_baton, uuid, pool);
}

static svn_error_t *compat_get_repos_root(void *session_baton,
                                          const char **url,
                                          apr_pool_t *pool)
{
  return VTBL.get_repos_root(session_baton, url, pool);
}

static svn_error_t *compat_get_locations(void *session_baton,
                                         apr_hash_t **locations,
                                         const char *path,
                                         svn_revnum_t peg_revision,
                                         apr_array_header_t *location_revs,
                                         apr_pool_t *pool)
{
  return VTBL.get_locations(session_baton, locations, path, peg_revision,
                            location_revs, pool);
}

static svn_error_t *compat_get_file_revs(void *session_baton,
                                         const char *path,
                                         svn_revnum_t start,
                                         svn_revnum_t end,
                                         svn_ra_file_rev_handler_t handler,
                                         void *handler_baton,
                                         apr_pool_t *pool)
{
  svn_file_rev_handler_t handler2;
  void *handler2_baton;

  svn_compat_wrap_file_rev_handler(&handler2, &handler2_baton,
                                   handler, handler_baton,
                                   pool);

  return VTBL.get_file_revs(session_baton, path, start, end,
                            FALSE, /* include merged revisions */
                            handler2, handler2_baton, pool);
}

static const svn_version_t *compat_get_version(void)
{
  return VTBL.get_version();
}


static const svn_ra_plugin_t compat_plugin = {
  NAME,
  DESCRIPTION,
  compat_open,
  compat_get_latest_revnum,
  compat_get_dated_revision,
  compat_change_rev_prop,
  compat_rev_proplist,
  compat_rev_prop,
  compat_get_commit_editor,
  compat_get_file,
  compat_get_dir,
  compat_do_update,
  compat_do_switch,
  compat_do_status,
  compat_do_diff,
  compat_get_log,
  compat_check_path,
  compat_get_uuid,
  compat_get_repos_root,
  compat_get_locations,
  compat_get_file_revs,
  compat_get_version
};

svn_error_t *
COMPAT_INITFUNC(int abi_version,
                apr_pool_t *pool,
                apr_hash_t *hash)
{
  const svn_ra__vtable_t *vtable;
  const char * const * schemes;

  if (abi_version < 1
      || abi_version > SVN_RA_ABI_VERSION)
    return svn_error_createf(SVN_ERR_RA_UNSUPPORTED_ABI_VERSION, NULL,
                             _("Unsupported RA plugin ABI version (%d) "
                               "for %s"), abi_version, NAME);

  /* We call the new init function so it can check library dependencies or
     do other initialization things.  We fake the loader version, since we
     rely on the ABI version check instead. */
  SVN_ERR(INITFUNC(VTBL.get_version(), &vtable, pool));

  schemes = VTBL.get_schemes(pool);

  for (; *schemes != NULL; ++schemes)
    apr_hash_set(hash, *schemes, APR_HASH_KEY_STRING, &compat_plugin);

  return SVN_NO_ERROR;
}
