/*
 * merge.c: handle the MERGE response processing
 *
 * ====================================================================
 *    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_buckets.h>
#include <apr_xml.h>
#include <apr_hash.h>

#include <httpd.h>
#include <util_filter.h>

#include "svn_hash.h"
#include "svn_pools.h"
#include "svn_fs.h"
#include "svn_props.h"
#include "svn_xml.h"

#include "dav_svn.h"

#include "private/svn_fspath.h"

/* #################################################################

   These functions are currently *VERY* SVN specific.

   * we don't check prop_elem for what the client requested
   * we presume a baseline was checked out into the activity, and is
     part of the MERGE
   * we presume that all "changed" files/dirs were checked out into
     the activity and are part of the MERGE
     (not sure if this is SVN specific; I can't see how a file/dir
      would be part of the new revision if a working resource had
      not been created for it)
   * we return some props for some resources, and a different set for
     other resources (to keep the wire smaller for now)

   At some point in the future, we'll want to make this "real". Especially
   for proper interoperability.

   #################################################################
*/



/* -------------------------------------------------------------------------
   PRIVATE HELPER FUNCTIONS
*/

/* send a response to the client for this baton */
static svn_error_t *
send_response(const dav_svn_repos *repos,
              svn_fs_root_t *root,
              const char *path,
              svn_boolean_t is_dir,
              ap_filter_t *output,
              apr_bucket_brigade *bb,
              apr_pool_t *pool)
{
  const char *href;
  const char *vsn_url;
  apr_status_t status;
  svn_revnum_t rev_to_use;

  href = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_PUBLIC,
                            SVN_IGNORED_REVNUM, path, 0 /* add_href */, pool);
  rev_to_use = dav_svn__get_safe_cr(root, path, pool);
  vsn_url = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_VERSION,
                               rev_to_use, path, FALSE /* add_href */, pool);
  status = ap_fputstrs(output, bb,
                       "<D:response>" DEBUG_CR
                       "<D:href>",
                       apr_xml_quote_string(pool, href, 1),
                       "</D:href>" DEBUG_CR
                       "<D:propstat><D:prop>" DEBUG_CR,
                       is_dir
                         ? "<D:resourcetype><D:collection/></D:resourcetype>"
                         : "<D:resourcetype/>",
                       DEBUG_CR,
                       "<D:checked-in><D:href>",
                       apr_xml_quote_string(pool, vsn_url, 1),
                       "</D:href></D:checked-in>" DEBUG_CR
                       "</D:prop>" DEBUG_CR
                       "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                       "</D:propstat>" DEBUG_CR
                       "</D:response>" DEBUG_CR,
                       NULL);
  if (status != APR_SUCCESS)
    return svn_error_wrap_apr(status, "Can't write response to output");

  return SVN_NO_ERROR;
}


static svn_error_t *
do_resources(const dav_svn_repos *repos,
             svn_fs_root_t *root,
             svn_revnum_t revision,
             ap_filter_t *output,
             apr_bucket_brigade *bb,
             apr_pool_t *pool)
{
  svn_fs_path_change_iterator_t *iterator;
  svn_fs_path_change3_t *change;

  /* Change lists can have >100000 entries, so we must make sure to release
     any collection as soon as possible.  Allocate them in SUBPOOL. */
  apr_pool_t *subpool = svn_pool_create(pool);
  apr_hash_t *sent = apr_hash_make(subpool);

  /* Standard iteration pool. */
  apr_pool_t *iterpool = svn_pool_create(subpool);

  /* Fetch the paths changed in this revision.  This will contain
     everything except otherwise-unchanged parent directories of added
     and deleted things.  Also, note that deleted things don't merit
     responses of their own -- they are considered modifications to
     their parent.  */
  SVN_ERR(svn_fs_paths_changed3(&iterator, root, subpool, subpool));
  SVN_ERR(svn_fs_path_change_get(&change, iterator));

  while (change)
    {
      svn_boolean_t send_self;
      svn_boolean_t send_parent;
      const char *path = change->path.data;

      svn_pool_clear(iterpool);

      /* Figure out who needs to get sent. */
      switch (change->change_kind)
        {
        case svn_fs_path_change_delete:
          send_self = FALSE;
          send_parent = TRUE;
          break;

        case svn_fs_path_change_add:
        case svn_fs_path_change_replace:
          send_self = TRUE;
          send_parent = TRUE;
          break;

        case svn_fs_path_change_modify:
        default:
          send_self = TRUE;
          send_parent = FALSE;
          break;
        }

      if (send_self)
        {
          /* If we haven't already sent this path, send it (and then
             remember that we sent it). */
          if (! apr_hash_get(sent, path, change->path.len))
            {
              svn_node_kind_t kind;
              SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool));
              SVN_ERR(send_response(repos, root, change->path.data,
                                    kind == svn_node_dir,
                                    output, bb, iterpool));

              /* The paths in CHANGES are unique, i.e. they can only
               * clash with those that we end in the SEND_PARENT case.
               *
               * Because file paths cannot be the parent of other paths,
               * we only need to track non-file paths. */
              if (change->node_kind != svn_node_file)
                {
                  path = apr_pstrmemdup(subpool, path, change->path.len);
                  apr_hash_set(sent, path, change->path.len, (void *)1);
                }
            }
        }
      if (send_parent)
        {
          const char *parent = svn_fspath__dirname(path, iterpool);
          if (! svn_hash_gets(sent, parent))
            {
              SVN_ERR(send_response(repos, root, parent,
                                    TRUE, output, bb, iterpool));
              svn_hash_sets(sent, apr_pstrdup(subpool, parent), (void *)1);
            }
        }

      SVN_ERR(svn_fs_path_change_get(&change, iterator));
    }

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}



/* -------------------------------------------------------------------------
   PUBLIC FUNCTIONS
*/

dav_error *
dav_svn__merge_response(ap_filter_t *output,
                        const dav_svn_repos *repos,
                        svn_revnum_t new_rev,
                        const char *post_commit_err,
                        apr_xml_elem *prop_elem,
                        svn_boolean_t disable_merge_response,
                        apr_pool_t *pool)
{
  apr_bucket_brigade *bb;
  svn_fs_root_t *root;
  svn_error_t *serr;
  const char *vcc;
  const char *rev;
  svn_string_t *creationdate, *creator_displayname;
  const char *post_commit_err_elem = NULL,
             *post_commit_header_info = NULL;
  apr_status_t status;
  apr_hash_t *revprops;

  serr = svn_fs_revision_root(&root, repos->fs, new_rev, pool);
  if (serr != NULL)
    {
      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "Could not open the FS root for the "
                                  "revision just committed.",
                                  repos->pool);
    }

  bb = apr_brigade_create(pool, output->c->bucket_alloc);

  /* prep some strings */

  /* the HREF for the baseline is actually the VCC */
  vcc = dav_svn__build_uri(repos, DAV_SVN__BUILD_URI_VCC, SVN_IGNORED_REVNUM,
                           NULL, FALSE /* add_href */, pool);

  /* the version-name of the baseline is the revision number */
  rev = apr_psprintf(pool, "%ld", new_rev);

  /* get the post-commit hook stderr, if any */
  if (post_commit_err)
    {
      post_commit_header_info = apr_psprintf(pool,
                                             " xmlns:S=\"%s\"",
                                             SVN_XML_NAMESPACE);
      post_commit_err_elem = apr_psprintf(pool,
                                          "<S:post-commit-err>%s"
                                          "</S:post-commit-err>",
                                          apr_xml_quote_string(pool,
                                                               post_commit_err,
                                                               0));
    }
  else
    {
      post_commit_header_info = "" ;
      post_commit_err_elem = "" ;
    }


  /* get the creationdate and creator-displayname of the new revision, too. */
  serr = svn_fs_revision_proplist2(&revprops, repos->fs, new_rev,
                                   TRUE, pool, pool);
  if (serr != NULL)
    {
      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "Could not get date and author of newest "
                                  "revision", repos->pool);
    }

  creationdate = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
  creator_displayname = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);

  status = ap_fputstrs(output, bb,
                     DAV_XML_HEADER DEBUG_CR
                     "<D:merge-response xmlns:D=\"DAV:\"",
                     post_commit_header_info,
                     ">" DEBUG_CR
                     "<D:updated-set>" DEBUG_CR

                     /* generate a response for the new baseline */
                     "<D:response>" DEBUG_CR
                     "<D:href>",
                     apr_xml_quote_string(pool, vcc, 1),
                     "</D:href>" DEBUG_CR
                     "<D:propstat><D:prop>" DEBUG_CR
                     /* ### this is wrong. it's a VCC, not a baseline. but
                        ### we need to tell the client to look at *this*
                        ### resource for the version-name. */
                     "<D:resourcetype><D:baseline/></D:resourcetype>" DEBUG_CR,
                     post_commit_err_elem, DEBUG_CR
                     "<D:version-name>", rev, "</D:version-name>" DEBUG_CR,
                     NULL);
  if (status != APR_SUCCESS)
    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
                              0, status,
                              "Could not write output");

  if (creationdate)
    {
      status = ap_fputstrs(output, bb,
                         "<D:creationdate>",
                         apr_xml_quote_string(pool, creationdate->data, 1),
                         "</D:creationdate>" DEBUG_CR,
                         NULL);
      if (status != APR_SUCCESS)
        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
                                  0, status,
                                  "Could not write output");
    }
  if (creator_displayname)
    {
      status = ap_fputstrs(output, bb,
                         "<D:creator-displayname>",
                         apr_xml_quote_string(pool,
                                              creator_displayname->data, 1),
                         "</D:creator-displayname>" DEBUG_CR,
                         NULL);
      if (status != APR_SUCCESS)
        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
                                  0, status,
                                  "Could not write output");
    }
  status = ap_fputstrs(output, bb,
                     "</D:prop>" DEBUG_CR
                     "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                     "</D:propstat>" DEBUG_CR
                     "</D:response>" DEBUG_CR,

                     NULL);
  if (status != APR_SUCCESS)
    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
                              0, status,
                              "Could not write output");

  /* ONLY have dir_delta drive the editor if the caller asked us to
     generate a full MERGE response.  svn clients can ask us to
     suppress this walk by sending specific request headers. */
  if (! disable_merge_response)
    {
      /* Now we need to generate responses for all the resources which
         changed.  This is done through a delta of the two roots.

         Note that a directory is not marked when open_dir is seen
         (since it typically is used just for changing members in that
         directory); instead, we want for a property change (the only
         reason the client would need to fetch a new directory).

         ### we probably should say something about the dirs, so that
         ### we can pass back the new version URL */

      /* and go make me proud, boy! */
      serr = do_resources(repos, root, new_rev, output, bb, pool);
      if (serr != NULL)
        {
          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                      "Error constructing resource list.",
                                      repos->pool);
        }
    }

  /* wrap up the merge response */
  status = ap_fputs(output, bb,
                  "</D:updated-set>" DEBUG_CR
                  "</D:merge-response>" DEBUG_CR);
  if (status != APR_SUCCESS)
    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
                              0, status,
                              "Could not write output");

  /* send whatever is left in the brigade */
  status = ap_pass_brigade(output, bb);
  if (status != APR_SUCCESS)
    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR,
                              0, status,
                              "Could not write output");

  return NULL;
}
