/*
 * get-location-segments.c: mod_dav_svn REPORT handler for mapping
 *                          revision ranges to path locations along
 *                          the history of an object
 *
 * ====================================================================
 *    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_tables.h>
#include <apr_uuid.h>

#include <httpd.h>
#include <http_log.h>
#include <mod_dav.h>

#include "svn_fs.h"
#include "svn_xml.h"
#include "svn_repos.h"
#include "svn_dav.h"
#include "svn_time.h"
#include "svn_pools.h"
#include "svn_props.h"
#include "svn_dav.h"
#include "svn_base64.h"

#include "private/svn_fspath.h"

#include "../dav_svn.h"


struct location_segment_baton
{
  svn_boolean_t sent_opener;
  dav_svn__output *output;
  apr_bucket_brigade *bb;
  dav_svn__authz_read_baton arb;
};


/* Send the get-location-segments-report XML open tag if it hasn't
   been sent already.  */
static svn_error_t *
maybe_send_opener(struct location_segment_baton *b)
{
  if (! b->sent_opener)
    {
      SVN_ERR(dav_svn__brigade_puts(b->bb, b->output, DAV_XML_HEADER DEBUG_CR
                                    "<S:get-location-segments-report "
                                    "xmlns:S=\"" SVN_XML_NAMESPACE
                                    "\" xmlns:D=\"DAV:\">" DEBUG_CR));
      b->sent_opener = TRUE;
    }
  return SVN_NO_ERROR;
}


/* Implements `svn_location_segment_receiver_t'; helper for
   dav_svn__get_location_segments_report(). */
static svn_error_t *
location_segment_receiver(svn_location_segment_t *segment,
                          void *baton,
                          apr_pool_t *pool)
{
  struct location_segment_baton *b = baton;

  SVN_ERR(maybe_send_opener(b));

  if (segment->path)
    {
      const char *path_quoted = apr_xml_quote_string(pool, segment->path, 1);

      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                           "<S:location-segment path=\"%s\" "
                           "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
                           path_quoted,
                           segment->range_start, segment->range_end));
    }
  else
    {
      SVN_ERR(dav_svn__brigade_printf(b->bb, b->output,
                           "<S:location-segment "
                           "range-start=\"%ld\" range-end=\"%ld\"/>" DEBUG_CR,
                           segment->range_start, segment->range_end));
    }
  return SVN_NO_ERROR;
}


dav_error *
dav_svn__get_location_segments_report(const dav_resource *resource,
                                      const apr_xml_doc *doc,
                                      dav_svn__output *output)
{
  svn_error_t *serr;
  dav_error *derr = NULL;
  apr_bucket_brigade *bb;
  int ns;
  apr_xml_elem *child;
  const char *abs_path = NULL;
  svn_revnum_t peg_revision = SVN_INVALID_REVNUM;
  svn_revnum_t start_rev = SVN_INVALID_REVNUM;
  svn_revnum_t end_rev = SVN_INVALID_REVNUM;
  dav_svn__authz_read_baton arb;
  struct location_segment_baton location_segment_baton;

  /* 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");
    }

  /* Gather the parameters. */
  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, "peg-revision") == 0)
        {
          peg_revision = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                          resource->pool, 1));
        }
      else if (strcmp(child->name, "start-revision") == 0)
        {
          start_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                       resource->pool, 1));
        }
      else if (strcmp(child->name, "end-revision") == 0)
        {
          end_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                     resource->pool, 1));
        }
      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. */
          abs_path = svn_fspath__join(resource->info->repos_path, rel_path,
                                      resource->pool);
        }
    }

  /* Check that all parameters are present and valid. */
  if (! abs_path)
    return dav_svn__new_error_svn(resource->pool, HTTP_BAD_REQUEST, 0, 0,
                                  "Not all parameters passed");

  /* No START_REV or PEG_REVISION?  We'll use HEAD. */
  if (!SVN_IS_VALID_REVNUM(start_rev) || !SVN_IS_VALID_REVNUM(peg_revision))
    {
      svn_revnum_t youngest;

      serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
                                       resource->pool);
      if (serr != NULL)
        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                    "Could not determine youngest revision",
                                    resource->pool);

      if (!SVN_IS_VALID_REVNUM(start_rev))
        start_rev = youngest;
      if (!SVN_IS_VALID_REVNUM(peg_revision))
        peg_revision = youngest;
    }

  /* No END_REV?  We'll use 0. */
  if (!SVN_IS_VALID_REVNUM(end_rev))
    end_rev = 0;

  if (end_rev > start_rev)
    return dav_svn__new_error_svn(resource->pool, HTTP_BAD_REQUEST,
                                  SVN_ERR_FS_NO_SUCH_REVISION, 0,
                                  "End revision must not be younger than "
                                  "start revision");
  if (start_rev > peg_revision)
    return dav_svn__new_error_svn(resource->pool, HTTP_BAD_REQUEST,
                                  SVN_ERR_FS_NO_SUCH_REVISION, 0,
                                  "Start revision must not be younger than "
                                  "peg revision");

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

  /* Build the bucket brigade we'll use for output. */
  bb = apr_brigade_create(resource->pool,
                          dav_svn__output_get_bucket_alloc(output));

  /* Do what we came here for. */
  location_segment_baton.sent_opener = FALSE;
  location_segment_baton.output = output;
  location_segment_baton.bb = bb;
  if ((serr = svn_repos_node_location_segments(resource->info->repos->repos,
                                               abs_path, peg_revision,
                                               start_rev, end_rev,
                                               location_segment_receiver,
                                               &location_segment_baton,
                                               dav_svn__authz_read_func(&arb),
                                               &arb, resource->pool)))
    {
      derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, NULL,
                                  resource->pool);
      goto cleanup;
    }

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

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

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