/*
 * replay.c :  entry point for replay RA functions for ra_serf
 *
 * ====================================================================
 *    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 <apr_uri.h>
#include <serf.h>

#include "svn_pools.h"
#include "svn_ra.h"
#include "svn_dav.h"
#include "svn_hash.h"
#include "svn_xml.h"
#include "../libsvn_ra/ra_loader.h"
#include "svn_config.h"
#include "svn_delta.h"
#include "svn_base64.h"
#include "svn_path.h"
#include "svn_private_config.h"

#include "private/svn_string_private.h"

#include "ra_serf.h"


/*
 * This enum represents the current state of our XML parsing.
 */
typedef enum replay_state_e {
  INITIAL = XML_STATE_INITIAL,

  REPLAY_REPORT,
  REPLAY_TARGET_REVISION,
  REPLAY_OPEN_ROOT,
  REPLAY_OPEN_DIRECTORY,
  REPLAY_OPEN_FILE,
  REPLAY_ADD_DIRECTORY,
  REPLAY_ADD_FILE,
  REPLAY_DELETE_ENTRY,
  REPLAY_CLOSE_FILE,
  REPLAY_CLOSE_DIRECTORY,
  REPLAY_CHANGE_DIRECTORY_PROP,
  REPLAY_CHANGE_FILE_PROP,
  REPLAY_APPLY_TEXTDELTA
} replay_state_e;

#define S_ SVN_XML_NAMESPACE
static const svn_ra_serf__xml_transition_t replay_ttable[] = {
  { INITIAL, S_, "editor-report", REPLAY_REPORT,
    FALSE, { NULL }, TRUE },

  /* Replay just throws every operation as xml element directly
     in the replay report, so we can't really use the nice exit
     handling of the transition parser to handle clean callbacks */

  { REPLAY_REPORT, S_, "target-revision", REPLAY_TARGET_REVISION,
    FALSE, { "rev", NULL }, TRUE },

  { REPLAY_REPORT, S_, "open-root", REPLAY_OPEN_ROOT,
    FALSE, { "rev", NULL }, TRUE },

  { REPLAY_REPORT, S_, "open-directory", REPLAY_OPEN_DIRECTORY,
    FALSE, { "name", "rev", NULL }, TRUE },

  { REPLAY_REPORT, S_, "open-file", REPLAY_OPEN_FILE,
    FALSE, { "name", "rev", NULL }, TRUE },

  { REPLAY_REPORT, S_, "add-directory", REPLAY_ADD_DIRECTORY,
    FALSE, { "name", "?copyfrom-path", "?copyfrom-rev", NULL}, TRUE },

  { REPLAY_REPORT, S_, "add-file", REPLAY_ADD_FILE,
    FALSE, { "name", "?copyfrom-path", "?copyfrom-rev", NULL}, TRUE },

  { REPLAY_REPORT, S_, "delete-entry", REPLAY_DELETE_ENTRY,
    FALSE, { "name", "rev", NULL }, TRUE },

  { REPLAY_REPORT, S_, "close-file", REPLAY_CLOSE_FILE,
    FALSE, { "?checksum", NULL }, TRUE },

  { REPLAY_REPORT, S_, "close-directory", REPLAY_CLOSE_DIRECTORY,
    FALSE, { NULL }, TRUE },

  { REPLAY_REPORT, S_, "change-dir-prop", REPLAY_CHANGE_DIRECTORY_PROP,
    TRUE, { "name", "?del", NULL }, TRUE },

  { REPLAY_REPORT, S_, "change-file-prop", REPLAY_CHANGE_FILE_PROP,
    TRUE, { "name", "?del", NULL }, TRUE },

  { REPLAY_REPORT, S_, "apply-textdelta", REPLAY_APPLY_TEXTDELTA,
    FALSE, { "?checksum", NULL }, TRUE },

  { 0 }
};

/* Per directory/file state */
typedef struct replay_node_t {
  apr_pool_t *pool; /* pool allocating this node's data */
  svn_boolean_t file; /* file or dir */

  void *baton; /* node baton */
  svn_stream_t *stream; /* stream while handling txdata */

  struct replay_node_t *parent; /* parent node or NULL */
} replay_node_t;

/* Per revision replay report state */
typedef struct revision_report_t {
  apr_pool_t *pool; /* per revision pool */

  struct replay_node_t *current_node;
  struct replay_node_t *root_node;

  /* Are we done fetching this file?
     Handles book-keeping in multi-report case */
  svn_boolean_t *done;
  int *replay_reports; /* NULL or number of outstanding reports */

  /* callback to get an editor */
  svn_ra_replay_revstart_callback_t revstart_func;
  svn_ra_replay_revfinish_callback_t revfinish_func;
  void *replay_baton;

  /* replay receiver function and baton */
  const svn_delta_editor_t *editor;
  void *editor_baton;

  /* Path and revision used to filter replayed changes.  If
     INCLUDE_PATH is non-NULL, REVISION is unnecessary and will not be
     included in the replay REPORT.  (Because the REPORT is being
     aimed an HTTP v2 revision resource.)  */
  const char *include_path;
  svn_revnum_t revision;

  /* Information needed to create the replay report body */
  svn_revnum_t low_water_mark;
  svn_boolean_t send_deltas;

  /* Target and revision to fetch revision properties on */
  const char *revprop_target;
  svn_revnum_t revprop_rev;

  /* Revision properties for this revision. */
  apr_hash_t *rev_props;

  /* Handlers for the PROPFIND and REPORT for the current revision. */
  svn_ra_serf__handler_t *propfind_handler;
  svn_ra_serf__handler_t *report_handler; /* For done handler */

  svn_ra_serf__session_t *session;

} revision_report_t;

/* Conforms to svn_ra_serf__xml_opened_t */
static svn_error_t *
replay_opened(svn_ra_serf__xml_estate_t *xes,
              void *baton,
              int entered_state,
              const svn_ra_serf__dav_props_t *tag,
              apr_pool_t *scratch_pool)
{
  struct revision_report_t *ctx = baton;

  if (entered_state == REPLAY_REPORT)
    {
      /* Before we can continue, we need the revision properties. */
      SVN_ERR_ASSERT(!ctx->propfind_handler || ctx->propfind_handler->done);

      svn_ra_serf__keep_only_regular_props(ctx->rev_props, scratch_pool);

      if (ctx->revstart_func)
        {
          SVN_ERR(ctx->revstart_func(ctx->revision, ctx->replay_baton,
                                     &ctx->editor, &ctx->editor_baton,
                                     ctx->rev_props,
                                     ctx->pool));
        }
    }
  else if (entered_state == REPLAY_APPLY_TEXTDELTA)
    {
       struct replay_node_t *node = ctx->current_node;
       apr_hash_t *attrs;
       const char *checksum;
       svn_txdelta_window_handler_t handler;
       void *handler_baton;

       if (! node || ! node->file || node->stream)
         return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

       /* ### Is there a better way to access a specific attr here? */
       attrs = svn_ra_serf__xml_gather_since(xes, REPLAY_APPLY_TEXTDELTA);
       checksum = svn_hash_gets(attrs, "checksum");

       SVN_ERR(ctx->editor->apply_textdelta(node->baton, checksum, node->pool,
                                            &handler, &handler_baton));

       if (handler != svn_delta_noop_window_handler)
         {
            node->stream = svn_base64_decode(
                                    svn_txdelta_parse_svndiff(handler,
                                                              handler_baton,
                                                              TRUE,
                                                              node->pool),
                                    node->pool);
         }
    }

  return SVN_NO_ERROR;
}

/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
replay_closed(svn_ra_serf__xml_estate_t *xes,
              void *baton,
              int leaving_state,
              const svn_string_t *cdata,
              apr_hash_t *attrs,
              apr_pool_t *scratch_pool)
{
  struct revision_report_t *ctx = baton;

  if (leaving_state == REPLAY_REPORT)
    {
      if (ctx->current_node)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      if (ctx->revfinish_func)
        {
          SVN_ERR(ctx->revfinish_func(ctx->revision, ctx->replay_baton,
                                      ctx->editor, ctx->editor_baton,
                                      ctx->rev_props, scratch_pool));
        }
    }
  else if (leaving_state == REPLAY_TARGET_REVISION)
    {
      const char *revstr = svn_hash_gets(attrs, "rev");
      apr_int64_t rev;

      SVN_ERR(svn_cstring_atoi64(&rev, revstr));
      SVN_ERR(ctx->editor->set_target_revision(ctx->editor_baton,
                                               (svn_revnum_t)rev,
                                               scratch_pool));
    }
  else if (leaving_state == REPLAY_OPEN_ROOT)
    {
      const char *revstr = svn_hash_gets(attrs, "rev");
      apr_int64_t rev;
      apr_pool_t *root_pool = svn_pool_create(ctx->pool);

      if (ctx->current_node || ctx->root_node)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      ctx->root_node = apr_pcalloc(root_pool, sizeof(*ctx->root_node));
      ctx->root_node->pool = root_pool;

      ctx->current_node = ctx->root_node;

      SVN_ERR(svn_cstring_atoi64(&rev, revstr));
      SVN_ERR(ctx->editor->open_root(ctx->editor_baton, (svn_revnum_t)rev,
                                     root_pool,
                                     &ctx->current_node->baton));
    }
  else if (leaving_state == REPLAY_OPEN_DIRECTORY
           || leaving_state == REPLAY_OPEN_FILE
           || leaving_state == REPLAY_ADD_DIRECTORY
           || leaving_state == REPLAY_ADD_FILE)
    {
      struct replay_node_t *node;
      apr_pool_t *node_pool;
      const char *name = svn_hash_gets(attrs, "name");
      const char *rev_str;
      apr_int64_t rev;

      if (!ctx->current_node || ctx->current_node->file)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      node_pool = svn_pool_create(ctx->current_node->pool);
      node = apr_pcalloc(node_pool, sizeof(*node));
      node->pool = node_pool;
      node->parent = ctx->current_node;

      if (leaving_state == REPLAY_OPEN_DIRECTORY
          || leaving_state == REPLAY_OPEN_FILE)
        {
          rev_str = svn_hash_gets(attrs, "rev");
        }
      else
        rev_str = svn_hash_gets(attrs, "copyfrom-rev");

      if (rev_str)
        SVN_ERR(svn_cstring_atoi64(&rev, rev_str));
      else
        rev = SVN_INVALID_REVNUM;

      switch (leaving_state)
        {
          case REPLAY_OPEN_DIRECTORY:
            node->file = FALSE;
            SVN_ERR(ctx->editor->open_directory(name,
                                    ctx->current_node->baton,
                                    (svn_revnum_t)rev,
                                    node->pool,
                                    &node->baton));
            break;
          case REPLAY_OPEN_FILE:
            node->file = TRUE;
            SVN_ERR(ctx->editor->open_file(name,
                                    ctx->current_node->baton,
                                    (svn_revnum_t)rev,
                                    node->pool,
                                    &node->baton));
            break;
          case REPLAY_ADD_DIRECTORY:
            node->file = FALSE;
            SVN_ERR(ctx->editor->add_directory(
                                    name,
                                    ctx->current_node->baton,
                                    SVN_IS_VALID_REVNUM(rev)
                                        ? svn_hash_gets(attrs, "copyfrom-path")
                                        : NULL,
                                    (svn_revnum_t)rev,
                                    node->pool,
                                    &node->baton));
            break;
          case REPLAY_ADD_FILE:
            node->file = TRUE;
            SVN_ERR(ctx->editor->add_file(
                                    name,
                                    ctx->current_node->baton,
                                    SVN_IS_VALID_REVNUM(rev)
                                        ? svn_hash_gets(attrs, "copyfrom-path")
                                        : NULL,
                                    (svn_revnum_t)rev,
                                    node->pool,
                                    &node->baton));
            break;
          /* default: unreachable */
        }
      ctx->current_node = node;
    }
  else if (leaving_state == REPLAY_CLOSE_FILE)
    {
      struct replay_node_t *node = ctx->current_node;

      if (! node || ! node->file)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      SVN_ERR(ctx->editor->close_file(node->baton,
                                      svn_hash_gets(attrs, "checksum"),
                                      node->pool));
      ctx->current_node = node->parent;
      svn_pool_destroy(node->pool);
    }
  else if (leaving_state == REPLAY_CLOSE_DIRECTORY)
    {
      struct replay_node_t *node = ctx->current_node;

      if (! node || node->file)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      SVN_ERR(ctx->editor->close_directory(node->baton, node->pool));
      ctx->current_node = node->parent;
      svn_pool_destroy(node->pool);
    }
  else if (leaving_state == REPLAY_DELETE_ENTRY)
    {
      struct replay_node_t *parent_node = ctx->current_node;
      const char *name = svn_hash_gets(attrs, "name");
      const char *revstr = svn_hash_gets(attrs, "rev");
      apr_int64_t rev;

      if (! parent_node || parent_node->file)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      SVN_ERR(svn_cstring_atoi64(&rev, revstr));
      SVN_ERR(ctx->editor->delete_entry(name,
                                        (svn_revnum_t)rev,
                                        parent_node->baton,
                                        scratch_pool));
    }
  else if (leaving_state == REPLAY_CHANGE_FILE_PROP
           || leaving_state == REPLAY_CHANGE_DIRECTORY_PROP)
    {
      struct replay_node_t *node = ctx->current_node;
      const char *name;
      const svn_string_t *value;

      if (! node || node->file != (leaving_state == REPLAY_CHANGE_FILE_PROP))
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      name = svn_hash_gets(attrs, "name");

      if (svn_hash_gets(attrs, "del"))
        value = NULL;
      else
        value = svn_base64_decode_string(cdata, scratch_pool);

      if (node->file)
        {
          SVN_ERR(ctx->editor->change_file_prop(node->baton, name, value,
                                                scratch_pool));
        }
      else
        {
          SVN_ERR(ctx->editor->change_dir_prop(node->baton, name, value,
                                               scratch_pool));
        }
    }
  else if (leaving_state == REPLAY_APPLY_TEXTDELTA)
    {
      struct replay_node_t *node = ctx->current_node;

      if (! node || ! node->file)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      if (node->stream)
        SVN_ERR(svn_stream_close(node->stream));

      node->stream = NULL;
    }
  return SVN_NO_ERROR;
}

/* Conforms to svn_ra_serf__xml_cdata_t  */
static svn_error_t *
replay_cdata(svn_ra_serf__xml_estate_t *xes,
             void *baton,
             int current_state,
             const char *data,
             apr_size_t len,
             apr_pool_t *scratch_pool)
{
  struct revision_report_t *ctx = baton;

  if (current_state == REPLAY_APPLY_TEXTDELTA)
    {
      struct replay_node_t *node = ctx->current_node;

      if (! node || ! node->file)
        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);

      if (node->stream)
        {
          apr_size_t written = len;

          SVN_ERR(svn_stream_write(node->stream, data, &written));
          if (written != len)
            return svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF, NULL,
                                    _("Error writing stream: unexpected EOF"));
        }
    }

  return SVN_NO_ERROR;
}

/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_replay_body(serf_bucket_t **bkt,
                   void *baton,
                   serf_bucket_alloc_t *alloc,
                   apr_pool_t *pool /* request pool */,
                   apr_pool_t *scratch_pool)
{
  struct revision_report_t *ctx = baton;
  serf_bucket_t *body_bkt;

  body_bkt = serf_bucket_aggregate_create(alloc);

  svn_ra_serf__add_open_tag_buckets(body_bkt, alloc,
                                    "S:replay-report",
                                    "xmlns:S", SVN_XML_NAMESPACE,
                                    SVN_VA_NULL);

  /* If we have a non-NULL include path, we add it to the body and
     omit the revision; otherwise, the reverse. */
  if (ctx->include_path)
    {
      svn_ra_serf__add_tag_buckets(body_bkt,
                                   "S:include-path",
                                   ctx->include_path,
                                   alloc);
    }
  else
    {
      svn_ra_serf__add_tag_buckets(body_bkt,
                                   "S:revision",
                                   apr_ltoa(pool, ctx->revision),
                                   alloc);
    }
  svn_ra_serf__add_tag_buckets(body_bkt,
                               "S:low-water-mark",
                               apr_ltoa(pool, ctx->low_water_mark),
                               alloc);

  svn_ra_serf__add_tag_buckets(body_bkt,
                               "S:send-deltas",
                               apr_ltoa(pool, ctx->send_deltas),
                               alloc);

  svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "S:replay-report");

  *bkt = body_bkt;
  return SVN_NO_ERROR;
}

svn_error_t *
svn_ra_serf__replay(svn_ra_session_t *ra_session,
                    svn_revnum_t revision,
                    svn_revnum_t low_water_mark,
                    svn_boolean_t send_deltas,
                    const svn_delta_editor_t *editor,
                    void *edit_baton,
                    apr_pool_t *scratch_pool)
{
  struct revision_report_t ctx = { NULL };
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;
  const char *report_target;

  SVN_ERR(svn_ra_serf__report_resource(&report_target, session,
                                       scratch_pool));

  ctx.pool = svn_pool_create(scratch_pool);
  ctx.editor = editor;
  ctx.editor_baton = edit_baton;
  ctx.done = FALSE;
  ctx.revision = revision;
  ctx.low_water_mark = low_water_mark;
  ctx.send_deltas = send_deltas;
  ctx.rev_props = apr_hash_make(scratch_pool);

  xmlctx = svn_ra_serf__xml_context_create(replay_ttable,
                                           replay_opened, replay_closed,
                                           replay_cdata,
                                           &ctx,
                                           scratch_pool);

  handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
                                              scratch_pool);

  handler->method = "REPORT";
  handler->path = session->session_url.path;
  handler->body_delegate = create_replay_body;
  handler->body_delegate_baton = &ctx;
  handler->body_type = "text/xml";

  /* Not setting up done handler as we don't use a global context */

  SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));

  if (handler->sline.code != 200)
    SVN_ERR(svn_ra_serf__unexpected_status(handler));

  return SVN_NO_ERROR;
}

/* The maximum number of outstanding requests at any time. When this
 * number is reached, ra_serf will stop sending requests until
 * responses on the previous requests are received and handled.
 *
 * Some observations about serf which lead us to the current value.
 * ----------------------------------------------------------------
 *
 * We aim to keep serf's outgoing queue filled with enough requests so
 * the network bandwidth and server capacity is used
 * optimally. Originally we used 5 as the max. number of outstanding
 * requests, but this turned out to be too low.
 *
 * Serf doesn't exit out of the svn_ra_serf__context_run_wait loop as long as
 * it has data to send or receive. With small responses (revs of a few
 * kB), serf doesn't come out of this loop at all. So with
 * MAX_OUTSTANDING_REQUESTS set to a low number, there's a big chance
 * that serf handles those requests completely in its internal loop,
 * and only then gives us a chance to create new requests. This
 * results in hiccups, slowing down the whole process.
 *
 * With a larger MAX_OUTSTANDING_REQUESTS, like 100 or more, there's
 * more chance that serf can come out of its internal loop so we can
 * replenish the outgoing request queue.  There's no real disadvantage
 * of using a large number here, besides the memory used to store the
 * message, parser and handler objects (approx. 250 bytes).
 *
 * In my test setup peak performance was reached at max. 30-35
 * requests. So I added a small margin and chose 50.
 */
#define MAX_OUTSTANDING_REQUESTS 50

/* Implements svn_ra_serf__response_done_delegate_t for svn_ra_serf__replay_range */
static svn_error_t *
replay_done(serf_request_t *request,
            void *baton,
            apr_pool_t *scratch_pool)
{
  struct revision_report_t *ctx = baton;
  svn_ra_serf__handler_t *handler = ctx->report_handler;

  if (handler->server_error)
    return svn_ra_serf__server_error_create(handler, scratch_pool);
  else if (handler->sline.code != 200)
    return svn_error_trace(svn_ra_serf__unexpected_status(handler));

  *ctx->done = TRUE; /* Breaks out svn_ra_serf__context_run_wait */

  /* Are re replaying multiple revisions? */
  if (ctx->replay_reports)
    {
      (*ctx->replay_reports)--;
    }

  svn_pool_destroy(ctx->pool); /* Destroys handler and request! */

  return SVN_NO_ERROR;
}

/* Implements svn_ra_serf__request_header_delegate_t */
static svn_error_t *
setup_headers(serf_bucket_t *headers,
              void *baton,
              apr_pool_t *request_pool,
              apr_pool_t *scratch_pool)
{
  struct revision_report_t *ctx = baton;

  svn_ra_serf__setup_svndiff_accept_encoding(headers, ctx->session);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_ra_serf__replay_range(svn_ra_session_t *ra_session,
                          svn_revnum_t start_revision,
                          svn_revnum_t end_revision,
                          svn_revnum_t low_water_mark,
                          svn_boolean_t send_deltas,
                          svn_ra_replay_revstart_callback_t revstart_func,
                          svn_ra_replay_revfinish_callback_t revfinish_func,
                          void *replay_baton,
                          apr_pool_t *scratch_pool)
{
  svn_ra_serf__session_t *session = ra_session->priv;
  svn_revnum_t rev = start_revision;
  const char *report_target;
  int active_reports = 0;
  const char *include_path;
  svn_boolean_t done;
  apr_pool_t *subpool = svn_pool_create(scratch_pool);

  if (session->http20) {
      /* ### Auch... this doesn't work yet...

         This code relies on responses coming in in an exact order, while
         http2 does everything to deliver responses as fast as possible.

         With http/1.1 we were quite lucky that this worked, as serf doesn't
         promise in order delivery.... (Please do not use authz with keys
         that expire)

         For now fall back to the legacy callback in libsvn_ra that is
         used by all the other ra layers as workaround.

         ### TODO: Optimize
         */
      return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, NULL, NULL);
  }

  SVN_ERR(svn_ra_serf__report_resource(&report_target, session,
                                       subpool));

  /* Prior to 1.8, mod_dav_svn expect to get replay REPORT requests
     aimed at the session URL.  But that's incorrect -- these reports
     aren't about specific resources -- they are above revisions.  The
     path-based filtering offered by this API is just that: a filter
     applied to the full set of changes made in the revision.  As
     such, the correct target for these REPORT requests is the "me
     resource" (or, pre-http-v2, the default VCC).

     Our server should have told us if it supported this protocol
     correction.  If so, we aimed our report at the correct resource
     and include the filtering path as metadata within the report
     body.  Otherwise, we fall back to the pre-1.8 behavior and just
     wish for the best.

     See issue #4287:
     https://issues.apache.org/jira/browse/SVN-4287
  */
  if (session->supports_rev_rsrc_replay)
    {
      SVN_ERR(svn_ra_serf__get_relative_path(&include_path,
                                             session->session_url.path,
                                             session, subpool));
    }
  else
    {
      include_path = NULL;
    }

  while (active_reports || rev <= end_revision)
    {
      if (session->cancel_func)
        SVN_ERR(session->cancel_func(session->cancel_baton));

      /* Send pending requests, if any. Limit the number of outstanding
         requests to MAX_OUTSTANDING_REQUESTS. */
      if (rev <= end_revision  && active_reports < MAX_OUTSTANDING_REQUESTS)
        {
          struct revision_report_t *rev_ctx;
          svn_ra_serf__handler_t *handler;
          apr_pool_t *rev_pool = svn_pool_create(subpool);
          svn_ra_serf__xml_context_t *xmlctx;
          const char *replay_target;

          rev_ctx = apr_pcalloc(rev_pool, sizeof(*rev_ctx));
          rev_ctx->pool = rev_pool;
          rev_ctx->revstart_func = revstart_func;
          rev_ctx->revfinish_func = revfinish_func;
          rev_ctx->replay_baton = replay_baton;
          rev_ctx->done = &done;
          rev_ctx->replay_reports = &active_reports;
          rev_ctx->include_path = include_path;
          rev_ctx->revision = rev;
          rev_ctx->low_water_mark = low_water_mark;
          rev_ctx->send_deltas = send_deltas;
          rev_ctx->session = session;

          /* Request all properties of a certain revision. */
          rev_ctx->rev_props = apr_hash_make(rev_ctx->pool);

          if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
            {
              rev_ctx->revprop_target = apr_psprintf(rev_pool, "%s/%ld",
                                                     session->rev_stub, rev);
              rev_ctx->revprop_rev = SVN_INVALID_REVNUM;
            }
          else
            {
              rev_ctx->revprop_target = report_target;
              rev_ctx->revprop_rev = rev;
            }

          SVN_ERR(svn_ra_serf__create_propfind_handler(
                                              &rev_ctx->propfind_handler,
                                              session,
                                              rev_ctx->revprop_target,
                                              rev_ctx->revprop_rev,
                                              "0", all_props,
                                              svn_ra_serf__deliver_svn_props,
                                              rev_ctx->rev_props,
                                              rev_pool));

          /* Spin up the serf request for the PROPFIND.  */
          svn_ra_serf__request_create(rev_ctx->propfind_handler);

          /* Send the replay REPORT request. */
          if (session->supports_rev_rsrc_replay)
            {
              replay_target = apr_psprintf(rev_pool, "%s/%ld",
                                           session->rev_stub, rev);
            }
          else
            {
              replay_target = session->session_url.path;
            }

          xmlctx = svn_ra_serf__xml_context_create(replay_ttable,
                                           replay_opened, replay_closed,
                                           replay_cdata, rev_ctx,
                                           rev_pool);

          handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL,
                                                      rev_pool);

          handler->method = "REPORT";
          handler->path = replay_target;
          handler->body_delegate = create_replay_body;
          handler->body_delegate_baton = rev_ctx;
          handler->body_type = "text/xml";

          handler->done_delegate = replay_done;
          handler->done_delegate_baton = rev_ctx;

          handler->custom_accept_encoding = TRUE;
          handler->header_delegate = setup_headers;
          handler->header_delegate_baton = rev_ctx;

          rev_ctx->report_handler = handler;
          svn_ra_serf__request_create(handler);

          rev++;
          active_reports++;
        }

      /* Run the serf loop. */
      done = FALSE;
      {
        svn_error_t *err = svn_ra_serf__context_run_wait(&done, session,
                                                         subpool);

        if (err)
          {
            svn_pool_destroy(subpool); /* Unregister all requests! */
            return svn_error_trace(err);
          }
      }

      /* The done handler of reports decrements active_reports when a report
         is done. This same handler reports (fatal) report errors, so we can
         just loop here. */
    }

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}
#undef MAX_OUTSTANDING_REQUESTS
