/*
 * log.c: mod_dav_svn REPORT handler for querying revision log info
 *
 * ====================================================================
 *    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_pools.h>
#include <apr_strings.h>
#include <apr_xml.h>

#include <mod_dav.h>

#include "svn_repos.h"
#include "svn_string.h"
#include "svn_types.h"
#include "svn_base64.h"
#include "svn_xml.h"
#include "svn_path.h"
#include "svn_dav.h"
#include "svn_pools.h"
#include "svn_props.h"

#include "private/svn_log.h"
#include "private/svn_fspath.h"

#include "../dav_svn.h"


struct log_receiver_baton
{
  /* this buffers the output for a bit and is automatically flushed,
     at appropriate times, by the Apache filter system. */
  apr_bucket_brigade *bb;

  /* where to deliver the output */
  ap_filter_t *output;

  /* Whether we've written the <S:log-report> header.  Allows for lazy
     writes to support mod_dav-based error handling. */
  svn_boolean_t needs_header;

  /* Whether we've written the <S:log-item> header for the current revision.
     Allows for lazy XML node creation while receiving the data through
     callbacks. */
  svn_boolean_t needs_log_item;

  /* How deep we are in the log message tree.  We only need to surpress the
     SVN_INVALID_REVNUM message if the stack_depth is 0. */
  int stack_depth;

  /* whether the client requested any custom revprops */
  svn_boolean_t requested_custom_revprops;

  /* whether the client can handle encoded binary property values */
  svn_boolean_t encode_binary_props;

  /* Helper variables to force early bucket brigade flushes */
  int result_count;
  int next_forced_flush;
};


/* If LRB->needs_header is true, send the "<S:log-report>" start
   element and set LRB->needs_header to zero.  Else do nothing.
   This is basically duplicated in file_revs.c.  Consider factoring if
   duplicating again. */
static svn_error_t *
maybe_send_header(struct log_receiver_baton *lrb)
{
  if (lrb->needs_header)
    {
      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                    DAV_XML_HEADER DEBUG_CR
                                    "<S:log-report xmlns:S=\""
                                    SVN_XML_NAMESPACE "\" "
                                    "xmlns:D=\"DAV:\">" DEBUG_CR));
      lrb->needs_header = FALSE;
    }

  return SVN_NO_ERROR;
}

/* If LRB->needs_log_item is true, send the "<S:log-item>" start
   element and set LRB->needs_log_item to zero.  Else do nothing. */
static svn_error_t *
maybe_start_log_item(struct log_receiver_baton *lrb)
{
  if (lrb->needs_log_item)
    {
      SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output,
                                      "<S:log-item>" DEBUG_CR));
      lrb->needs_log_item = FALSE;
    }

  return SVN_NO_ERROR;
}

/* Utility for log_receiver opening a new XML element in LRB's brigade
   for LOG_ITEM and return the element's name in *ELEMENT.  Use POOL for
   temporary allocations.

   Call this function for items that may have a copy-from */
static svn_error_t *
start_path_with_copy_from(const char **element,
                          struct log_receiver_baton *lrb,
                          svn_repos_path_change_t *log_item,
                          apr_pool_t *pool)
{
  switch (log_item->change_kind)
    {
      case svn_fs_path_change_add: 
        *element = "S:added-path";
        break;

      case svn_fs_path_change_replace:
        *element = "S:replaced-path";
        break;

      default:
        /* Caller, you did wrong! */
        SVN_ERR_MALFUNCTION();
    }

  if (log_item->copyfrom_path
      && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev))
    SVN_ERR(dav_svn__brigade_printf
            (lrb->bb, lrb->output,
             "<%s copyfrom-path=\"%s\" copyfrom-rev=\"%ld\"",
             *element,
             apr_xml_quote_string(pool,
                                  log_item->copyfrom_path,
                                  1), /* escape quotes */
             log_item->copyfrom_rev));
  else
    SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output, "<%s", *element));

  return SVN_NO_ERROR;
}


/* This implements `svn_repos_path_change_receiver_t'.
   BATON is a `struct log_receiver_baton *'.  */
static svn_error_t *
log_change_receiver(void *baton,
                    svn_repos_path_change_t *change,
                    apr_pool_t *scratch_pool)
{
  struct log_receiver_baton *lrb = baton;
  const char *close_element = NULL;

  /* We must open the XML nodes for the report and log-item before
     sending the first changed path.

     Note that we can't get here for empty revisions that log() injects
     to indicate the end of a recursive merged rev sequence.
   */
  SVN_ERR(maybe_send_header(lrb));
  SVN_ERR(maybe_start_log_item(lrb));

  /* ### todo: is there a D: namespace equivalent for
      `changed-path'?  Should use it if so. */
  switch (change->change_kind)
    {
    case svn_fs_path_change_add:
    case svn_fs_path_change_replace:
      SVN_ERR(start_path_with_copy_from(&close_element, lrb,
                                        change, scratch_pool));
      break;

    case svn_fs_path_change_delete:
      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                    "<S:deleted-path"));
      close_element = "S:deleted-path";
      break;

    case svn_fs_path_change_modify:
      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                    "<S:modified-path"));
      close_element = "S:modified-path";
      break;

    default:
      break;
    }

  /* If we need to close the element, then send the attributes
      that apply to all changed items and then close the element. */
  if (close_element)
    SVN_ERR(dav_svn__brigade_printf
             (lrb->bb, lrb->output,
              " node-kind=\"%s\""
              " text-mods=\"%s\""
              " prop-mods=\"%s\">%s</%s>" DEBUG_CR,
              svn_node_kind_to_word(change->node_kind),
              change->text_mod ? "true" : "false",
              change->prop_mod ? "true" : "false",
              apr_xml_quote_string(scratch_pool, change->path.data, 0),
              close_element));

  return SVN_NO_ERROR;
}

/* This implements `svn_repos_log_entry_receiver_t'.
   BATON is a `struct log_receiver_baton *'.  */
static svn_error_t *
log_revision_receiver(void *baton,
                      svn_repos_log_entry_t *log_entry,
                      apr_pool_t *scratch_pool)
{
  struct log_receiver_baton *lrb = baton;

  SVN_ERR(maybe_send_header(lrb));

  if (log_entry->revision == SVN_INVALID_REVNUM)
    {
      /* If the stack depth is zero, we've seen the last revision, so don't
         send it, just return.  The footer will be sent later. */
      if (lrb->stack_depth == 0)
        return SVN_NO_ERROR;
      else
        lrb->stack_depth--;
    }

  /* If we have not received any path changes, the log-item XML node
     still needs to be opened.  Also, reset the controlling flag to
     prepare it for the next revision - if there should be one. */
  SVN_ERR(maybe_start_log_item(lrb));
  lrb->needs_log_item = TRUE;

  /* Path changes have been processed already. 
     Now send the remaining per-revision info. */
  SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output,
                                  "<D:version-name>%ld"
                                  "</D:version-name>" DEBUG_CR,
                                  log_entry->revision));

  if (log_entry->revprops)
    {
      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
      apr_hash_index_t *hi;
      for (hi = apr_hash_first(scratch_pool, log_entry->revprops);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          char *name;
          void *val;
          const svn_string_t *value;
          const char *encoding_str = "";

          svn_pool_clear(iterpool);
          apr_hash_this(hi, (void *)&name, NULL, &val);
          value = val;

          /* If the client is okay with us encoding binary (or really,
             any non-XML-safe) property values, do so as necessary. */
          if (lrb->encode_binary_props)
            {
              if (! svn_xml_is_xml_safe(value->data, value->len))
                {
                  value = svn_base64_encode_string2(value, TRUE, iterpool);
                  encoding_str = " encoding=\"base64\"";
                }
            }

          if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<D:creator-displayname%s>%s</D:creator-displayname>"
                     DEBUG_CR, encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
          else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
            /* ### this should be DAV:creation-date, but we need to format
               ### that date a bit differently */
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<S:date%s>%s</S:date>" DEBUG_CR, encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
          else if (strcmp(name, SVN_PROP_REVISION_LOG) == 0)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<D:comment%s>%s</D:comment>" DEBUG_CR, encoding_str,
                     apr_xml_quote_string(scratch_pool,
                                          svn_xml_fuzzy_escape(value->data,
                                                               iterpool), 0)));
          else
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<S:revprop name=\"%s\"%s>%s</S:revprop>" DEBUG_CR,
                     apr_xml_quote_string(iterpool, name, 0), encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
        }

      svn_pool_destroy(iterpool);
    }

  if (log_entry->has_children)
    {
      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output, "<S:has-children/>"));
      lrb->stack_depth++;
    }

  if (log_entry->subtractive_merge)
    SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                  "<S:subtractive-merge/>"));

  SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                "</S:log-item>" DEBUG_CR));

  /* In general APR will flush the brigade every 8000 bytes through the filter
     stack, but log items may not be generated that fast, especially in
     combination with authz and busy servers. We now explictly flush after
     log-item 4, 16, 64 and 256 to produce a few results fast.

     This introduces 4 full flushes of our brigade and the installed output
     filters at growing intervals and then falls back to the standard
     buffering of 8000 bytes + whatever buffers are added in output filters. */
  lrb->result_count++;
  if (lrb->result_count == lrb->next_forced_flush)
    {
      apr_status_t apr_err;

      /* This flush is similar to that in dav_svn__final_flush_or_error().

         Compared to using ap_filter_flush(), which we use in other place
         this adds a flush frame before flushing the brigade, to make output
         filters perform a flush as well */

      /* No brigade empty check. We want output filters to flush anyway */
      apr_err = ap_fflush(lrb->output, lrb->bb);
      if (apr_err)
        return svn_error_create(apr_err, NULL, NULL);

      /* Check for an aborted connection, just like our brigade write
         helper functions, since the brigade functions don't appear to
         be return useful errors when the connection is dropped. */
      if (lrb->output->c->aborted)
        return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED,
                                NULL, NULL);

      if (lrb->result_count < 256)
        lrb->next_forced_flush = lrb->next_forced_flush * 4;
    }

  return SVN_NO_ERROR;
}


dav_error *
dav_svn__log_report(const dav_resource *resource,
                    const apr_xml_doc *doc,
                    ap_filter_t *output)
{
  svn_error_t *serr;
  dav_error *derr = NULL;
  apr_xml_elem *child;
  struct log_receiver_baton lrb;
  dav_svn__authz_read_baton arb;
  const dav_svn_repos *repos = resource->info->repos;
  const char *target = NULL;
  int limit = 0;
  int ns;
  svn_boolean_t seen_revprop_element;

  /* These get determined from the request document. */
  svn_revnum_t start = SVN_INVALID_REVNUM;   /* defaults to HEAD */
  svn_revnum_t end = SVN_INVALID_REVNUM;     /* defaults to HEAD */
  svn_boolean_t discover_changed_paths = FALSE;      /* off by default */
  svn_boolean_t strict_node_history = FALSE;         /* off by default */
  svn_boolean_t include_merged_revisions = FALSE;    /* off by default */

  apr_array_header_t *revprops = apr_array_make(resource->pool, 3,
                                                sizeof(const char *));
  apr_array_header_t *paths
    = apr_array_make(resource->pool, 1, sizeof(const char *));

  /* Sanity check. */
  if (!resource->info->repos_path)
    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, 0,
                              "The request does not specify a repository path");
  ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
  if (ns == -1)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_BAD_REQUEST, 0, 0,
                                    "The request does not contain the 'svn:' "
                                    "namespace, so it is not going to have "
                                    "certain required elements");
    }

  /* If this is still FALSE after the loop, we haven't seen either of
     the revprop elements, meaning a pre-1.5 client; we'll return the
     standard author/date/log revprops. */
  seen_revprop_element = FALSE;

  lrb.requested_custom_revprops = FALSE;
  lrb.encode_binary_props = FALSE;
  for (child = doc->root->first_child; child != NULL; child = child->next)
    {
      /* if this element isn't one of ours, then skip it */
      if (child->ns != ns)
        continue;

      if (strcmp(child->name, "start-revision") == 0)
        start = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
      else if (strcmp(child->name, "end-revision") == 0)
        end = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
      else if (strcmp(child->name, "limit") == 0)
        {
          serr = svn_cstring_atoi(&limit,
                                  dav_xml_get_cdata(child, resource->pool, 1));
          if (serr)
            {
              return dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
                                          "Malformed CDATA in element "
                                          "\"limit\"", resource->pool);
            }
        }
      else if (strcmp(child->name, "discover-changed-paths") == 0)
        discover_changed_paths = TRUE; /* presence indicates positivity */
      else if (strcmp(child->name, "strict-node-history") == 0)
        strict_node_history = TRUE; /* presence indicates positivity */
      else if (strcmp(child->name, "include-merged-revisions") == 0)
        include_merged_revisions = TRUE; /* presence indicates positivity */
      else if (strcmp(child->name, "encode-binary-props") == 0)
        lrb.encode_binary_props = TRUE; /* presence indicates positivity */
      else if (strcmp(child->name, "all-revprops") == 0)
        {
          revprops = NULL; /* presence indicates fetch all revprops */
          seen_revprop_element = lrb.requested_custom_revprops = TRUE;
        }
      else if (strcmp(child->name, "no-revprops") == 0)
        {
          /* presence indicates fetch no revprops */

          seen_revprop_element = lrb.requested_custom_revprops = TRUE;
        }
      else if (strcmp(child->name, "revprop") == 0)
        {
          if (revprops)
            {
              /* We're not fetching all revprops, append to fetch list. */
              const char *name = dav_xml_get_cdata(child, resource->pool, 0);
              APR_ARRAY_PUSH(revprops, const char *) = name;
              if (!lrb.requested_custom_revprops
                  && strcmp(name, SVN_PROP_REVISION_AUTHOR) != 0
                  && strcmp(name, SVN_PROP_REVISION_DATE) != 0
                  && strcmp(name, SVN_PROP_REVISION_LOG) != 0)
                lrb.requested_custom_revprops = TRUE;
            }
          seen_revprop_element = TRUE;
        }
      else if (strcmp(child->name, "path") == 0)
        {
          const char *rel_path = dav_xml_get_cdata(child, resource->pool, 0);
          if ((derr = dav_svn__test_canonical(rel_path, resource->pool)))
            return derr;

          /* Force REL_PATH to be a relative path, not an fspath. */
          rel_path = svn_relpath_canonicalize(rel_path, resource->pool);

          /* Append the REL_PATH to the base FS path to get an
             absolute repository path. */
          target = svn_fspath__join(resource->info->repos_path, rel_path,
                                    resource->pool);
          APR_ARRAY_PUSH(paths, const char *) = target;
        }
      /* else unknown element; skip it */
    }

  if (!seen_revprop_element)
    {
      /* pre-1.5 client */
      APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR;
      APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_DATE;
      APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG;
    }

  /* Build authz read baton */
  arb.r = resource->info->r;
  arb.repos = resource->info->repos;

  /* Build log receiver baton */
  lrb.bb = apr_brigade_create(resource->pool,  /* not the subpool! */
                              output->c->bucket_alloc);
  lrb.output = output;
  lrb.needs_header = TRUE;
  lrb.needs_log_item = TRUE;
  lrb.stack_depth = 0;
  /* lrb.requested_custom_revprops set above */

  lrb.result_count = 0;
  lrb.next_forced_flush = 4;

  /* Our svn_log_entry_receiver_t sends the <S:log-report> header in
     a lazy fashion.  Before writing the first log message, it assures
     that the header has already been sent (checking the needs_header
     flag in our log_receiver_baton structure). */

  /* Send zero or more log items. */
  serr = svn_repos_get_logs5(repos->repos,
                             paths,
                             start,
                             end,
                             limit,
                             strict_node_history,
                             include_merged_revisions,
                             revprops,
                             dav_svn__authz_read_func(&arb),
                             &arb,
                             discover_changed_paths ? log_change_receiver
                                                    : NULL,
                             &lrb,
                             log_revision_receiver,
                             &lrb,
                             resource->pool);
  if (serr)
    {
      derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, NULL,
                                  resource->pool);
      goto cleanup;
    }

  if ((serr = maybe_send_header(&lrb)))
    {
      derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "Error beginning REPORT response.",
                                  resource->pool);
      goto cleanup;
    }

  if ((serr = dav_svn__brigade_puts(lrb.bb, lrb.output,
                                    "</S:log-report>" DEBUG_CR)))
    {
      derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "Error ending REPORT response.",
                                  resource->pool);
      goto cleanup;
    }

 cleanup:

  dav_svn__operational_log(resource->info,
                           svn_log__log(paths, start, end, limit,
                                        discover_changed_paths,
                                        strict_node_history,
                                        include_merged_revisions, revprops,
                                        resource->pool));

  return dav_svn__final_flush_or_error(resource->info->r, lrb.bb, output,
                                       derr, resource->pool);
}
