/*
 * merge.c: handle the MERGE response processing
 *
 * ====================================================================
 * Copyright (c) 2000-2002 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

#include <apr_pools.h>
#include <apr_buckets.h>
#include <apr_xml.h>

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

#include "svn_pools.h"
#include "svn_fs.h"
#include "svn_repos.h"

#include "dav_svn.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.

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

typedef struct {
  apr_pool_t *pool;
  ap_filter_t *output;
  apr_bucket_brigade *bb;
  svn_fs_root_t *root;
  const dav_svn_repos *repos;

} merge_response_ctx;

typedef struct mr_baton {
  merge_response_ctx *mrc;

  /* for directories, this is a subpool. otherwise, the pool to use. */
  apr_pool_t *pool;

  /* path for this baton's corresponding FS object */
  const char *path;

  /* for a directory, have we seen a change yet? */
  svn_boolean_t seen_change;

} mr_baton;



/* -------------------------------------------------------------------------

   PRIVATE HELPER FUNCTIONS
*/

static mr_baton *make_child_baton(mr_baton *parent, const char *name,
                                  svn_boolean_t is_dir)
{
  apr_pool_t *pool;
  mr_baton *subdir;

  if (is_dir)
    pool = svn_pool_create(parent->pool);
  else
    pool = parent->pool;

  subdir = apr_pcalloc(pool, sizeof(*subdir));
  subdir->mrc = parent->mrc;
  subdir->pool = pool;

  if (parent->path[1] == '\0')  /* must be "/" */
    subdir->path = apr_pstrcat(pool, "/", name, NULL);
  else
    subdir->path = apr_pstrcat(pool, parent->path, "/", name, NULL);

  return subdir;
}

/* send a response to the client for this baton */
static svn_error_t *send_response(mr_baton *baton, svn_boolean_t is_dir)
{
  merge_response_ctx *mrc = baton->mrc;
  const char *href;
  const char *rt;
  svn_fs_id_t *id;
  svn_stringbuf_t *stable_id;
  const char *vsn_url;
  apr_status_t status;

  href = dav_svn_build_uri(mrc->repos, DAV_SVN_BUILD_URI_PUBLIC,
                           SVN_IGNORED_REVNUM, baton->path,
                           0 /* add_href */, baton->pool);

  rt = is_dir
    ? "<D:resourcetype><D:collection/></D:resourcetype>" DEBUG_CR
    : "<D:resourcetype/>" DEBUG_CR;

  SVN_ERR( svn_fs_node_id(&id, mrc->root, baton->path, baton->pool) );

  stable_id = svn_fs_unparse_id(id, baton->pool);
  svn_stringbuf_appendcstr(stable_id, baton->path);

  vsn_url = dav_svn_build_uri(mrc->repos, DAV_SVN_BUILD_URI_VERSION,
                              SVN_INVALID_REVNUM, stable_id->data,
                              0 /* add_href */, baton->pool);

  status = ap_fputstrs(mrc->output, mrc->bb,
                       "<D:response>" DEBUG_CR
                       "<D:href>", 
                       apr_xml_quote_string (baton->pool, href, 1),
                       "</D:href>" DEBUG_CR
                       "<D:propstat><D:prop>" DEBUG_CR,
                       rt,
                       "<D:checked-in><D:href>",
                       apr_xml_quote_string (baton->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_create(status, 0, NULL, baton->pool,
                            "could not write response to output");

  return APR_SUCCESS;
}


/* -------------------------------------------------------------------------

   EDITOR FUNCTIONS
*/

static svn_error_t *mr_open_root(void *edit_baton,
                                 svn_revnum_t base_revision,
                                 void **root_baton)
{
  merge_response_ctx *mrc = edit_baton;
  apr_pool_t *pool;
  mr_baton *b;

  /* note that we create a subpool; the root_baton is passed to the
     close_directory callback, where we will destroy the pool. */
  pool = svn_pool_create(mrc->pool);
  b = apr_pcalloc(pool, sizeof(*b));
  b->mrc = mrc;
  b->pool = pool;
  b->path = "/";

  *root_baton = b;
  return NULL;
}

static svn_error_t *mr_delete_entry(svn_stringbuf_t *name,
                                    svn_revnum_t revision,
                                    void *parent_baton)
{
  mr_baton *parent = parent_baton;

  /* Removing an item is an explicit change to the parent. Mark it so the
     client will get the data on the new parent. */
  parent->seen_change = TRUE;

  return NULL;
}

static svn_error_t *mr_add_directory(svn_stringbuf_t *name,
                                     void *parent_baton,
                                     svn_stringbuf_t *copyfrom_path,
                                     svn_revnum_t copyfrom_revision,
                                     void **child_baton)
{
  mr_baton *parent = parent_baton;
  mr_baton *subdir = make_child_baton(parent, name->data, TRUE);

  /* pretend that we've already seen a change for this dir (so that a prop
     change won't generate a second response) */
  subdir->seen_change = TRUE;

  /* the response for this directory will occur at close_directory time */

  /* Adding a subdir is an explicit change to the parent. Mark it so the
     client will get the data on the new parent. */
  parent->seen_change = TRUE;

  *child_baton = subdir;
  return NULL;
}

static svn_error_t *mr_open_directory(svn_stringbuf_t *name,
                                      void *parent_baton,
                                      svn_revnum_t base_revision,
                                      void **child_baton)
{
  mr_baton *parent = parent_baton;
  mr_baton *subdir = make_child_baton(parent, name->data, TRUE);

  /* Don't issue a response until we see a prop change, or a file/subdir
     is added/removed inside this directory. */

  *child_baton = subdir;
  return NULL;
}

static svn_error_t *mr_change_dir_prop(void *dir_baton,
                                       svn_stringbuf_t *name,
                                       svn_stringbuf_t *value)
{
  mr_baton *dir = dir_baton;

  /* okay, this qualifies as a change, and we need to tell the client
     (which happens at close_directory time). */
  dir->seen_change = TRUE;

  return NULL;
}

static svn_error_t *mr_close_directory(void *dir_baton)
{
  mr_baton *dir = dir_baton;

  /* if we ever saw a change for this directory, then issue a response
     for it. */
  if (dir->seen_change)
    {
      SVN_ERR( send_response(dir, TRUE /* is_dir */) );
    }

  svn_pool_destroy(dir->pool);

  return NULL;
}

static svn_error_t *mr_add_file(svn_stringbuf_t *name,
                                void *parent_baton,
                                svn_stringbuf_t *copy_path,
                                svn_revnum_t copy_revision,
                                void **file_baton)
{
  mr_baton *parent = parent_baton;
  mr_baton *file = make_child_baton(parent, name->data, FALSE);

  /* We wait until close_file to issue a response for this. */

  /* Adding a file is an explicit change to the parent. Mark it so the
     client will get the data on the new parent. */
  parent->seen_change = TRUE;

  *file_baton = file;
  return NULL;
}

static svn_error_t *mr_open_file(svn_stringbuf_t *name,
                                 void *parent_baton,
                                 svn_revnum_t base_revision,
                                 void **file_baton)
{
  mr_baton *parent = parent_baton;
  mr_baton *file = make_child_baton(parent, name->data, FALSE);

  /* We wait until close_file to issue a response for this. */

  *file_baton = file;
  return NULL;
}

static svn_error_t *mr_close_file(void *file_baton)
{
  /* nothing to do except for sending the response. */
  return send_response(file_baton, FALSE /* is_dir */);
}


/* -------------------------------------------------------------------------

   PUBLIC FUNCTIONS
*/

dav_error * dav_svn__merge_response(ap_filter_t *output,
                                    const dav_svn_repos *repos,
                                    svn_revnum_t new_rev,
                                    apr_xml_elem *prop_elem,
                                    apr_pool_t *pool)
{
  apr_bucket_brigade *bb;
  svn_fs_root_t *committed_root;
  svn_fs_root_t *previous_root;
  svn_error_t *serr;
  const char *vcc;
  char revbuf[20];      /* long enough for %ld */
  svn_string_t *creationdate, *creator_displayname;
  apr_hash_t *revs;
  svn_revnum_t *rev_ptr;
  svn_delta_edit_fns_t *editor;
  merge_response_ctx mrc = { 0 };

  serr = svn_fs_revision_root(&committed_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.");
    }
  serr = svn_fs_revision_root(&previous_root, repos->fs, new_rev - 1, pool);
  if (serr != NULL)
    {
      return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                 "Could not open the FS root for the "
                                 "previous revision.");
    }

  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, 0 /* add_href */, pool);

  /* the version-name of the baseline is the revision number */
  sprintf(revbuf, "%ld", new_rev);

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


  (void) ap_fputstrs(output, bb,
                     DAV_XML_HEADER DEBUG_CR
                     "<D:merge-response xmlns:D=\"DAV:\">" 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
                     "<D:version-name>", revbuf, "</D:version-name>" DEBUG_CR
                     "<D:creationdate>", creationdate->data, 
                                     "</D:creationdate>" DEBUG_CR
                     "<D:creator-displayname>", creator_displayname->data,
                                     "</D:creator-displayname>" 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);

  /* 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 */

  /* ### hrm. needing this hash table feels wonky. */
  revs = apr_hash_make(pool);
  rev_ptr = apr_palloc(pool, sizeof(*rev_ptr));
  *rev_ptr = new_rev - 1;
  apr_hash_set(revs, "", APR_HASH_KEY_STRING, rev_ptr);

  /* set up the editor for the delta process */
  editor = svn_delta_old_default_editor(pool);
  editor->open_root = mr_open_root;
  editor->delete_entry = mr_delete_entry;
  editor->add_directory = mr_add_directory;
  editor->open_directory = mr_open_directory;
  editor->change_dir_prop = mr_change_dir_prop;
  editor->close_directory = mr_close_directory;
  editor->add_file = mr_add_file;
  editor->open_file = mr_open_file;
  editor->close_file = mr_close_file;

  /* set up the merge response context */
  mrc.pool = pool;
  mrc.output = output;
  mrc.bb = bb;
  mrc.root = committed_root;
  mrc.repos = repos;

  serr = svn_repos_dir_delta(previous_root, "/",
                             NULL,      /* ### should fix */
                             revs,
                             committed_root, "/",
                             editor, &mrc, 
                             FALSE, /* don't bother with text-deltas */
                             TRUE, /* Do recurse into subdirectories */
                             FALSE, /* Do not allow copyfrom args */
                             pool);
  if (serr != NULL)
    {
      return dav_svn_convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                 "could not process the merge delta.");
    }

  /* wrap up the merge response */
  (void) ap_fputs(output, bb,
                  "</D:updated-set>" DEBUG_CR
                  "</D:merge-response>" DEBUG_CR);

  /* send whatever is left in the brigade */
  (void) ap_pass_brigade(output, bb);

  return NULL;
}


/* ----------------------------------------------------------------
 * local variables:
 * eval: (load-file "../../tools/dev/svn-dev.el")
 * end:
 */
