/* svn-push.c --- propagate changesets from one (networked) repository to
 * a different (networked) repository.
 *
 * ====================================================================
 * Copyright (c) 2003-2007, 2009 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 <stdio.h>

#include "svn_delta.h"
#include "svn_cmdline.h"
#include "svn_config.h"
#include "svn_path.h"
#include "svn_pools.h"
#include "svn_props.h"
#include "svn_ra.h"

/* Implements svn_commit_callback2_t. */
static svn_error_t *
my_commit_callback (const svn_commit_info_t *ci, void *baton, apr_pool_t *pool)
{
  printf ("Commiting Rev. %ld at date \"%s\", by "
          "author \"%s\"\n", ci->revision, ci->date, ci->author);
  if (ci->post_commit_err)
    printf ("Post-commit Error: %s\n", ci->post_commit_err);
  return SVN_NO_ERROR;
}


/* Implements svn_ra_callbacks2_t.open_tmp_file */
static svn_error_t *
open_tmp_file (apr_file_t **fp, void *callback_baton, apr_pool_t *pool)
{
  const char *path;

  SVN_ERR (svn_io_temp_dir (&path, pool));
  path = svn_path_join (path, "tempfile", pool);
  SVN_ERR (svn_io_open_unique_file (fp, NULL, path, ".tmp", TRUE, pool));

  return SVN_NO_ERROR;
}


svn_error_t *(*old_change_file_prop) (void *file_baton,
                                      const char *name,
                                      const svn_string_t *value,
                                      apr_pool_t *pool);

/* Implements svn_ra_callbacks2_t.change_file_prop */
static svn_error_t *
new_change_file_prop (void *file_baton, const char *name,
                      const svn_string_t *value, apr_pool_t *pool)
{
  if (svn_property_kind (NULL, name) != svn_prop_regular_kind)
    return SVN_NO_ERROR;
  else
    return old_change_file_prop (file_baton, name, value, pool);
}


svn_error_t *(*old_change_dir_prop) (void *dir_baton,
                                     const char *name,
                                     const svn_string_t *value,
                                     apr_pool_t *pool);

/* Implements svn_ra_callbacks2_t.change_dir_prop */
static svn_error_t *
new_change_dir_prop (void *dir_baton, const char *name,
                     const svn_string_t *value, apr_pool_t *pool)
{
  if (svn_property_kind (NULL, name) != svn_prop_regular_kind)
    return SVN_NO_ERROR;
  else
    return old_change_dir_prop (dir_baton, name, value, pool);
}


static svn_error_t *
do_job (const char *src_url, const char *dest_url, int start_rev, int end_rev,
        apr_pool_t *pool)
{
  apr_hash_t *config;
  svn_config_t *cfg;
  svn_auth_baton_t *ab;
  svn_ra_callbacks2_t *callbacks;
  svn_ra_session_t *ra_src, *ra_dest;
  const svn_delta_editor_t *editor;
  svn_delta_editor_t *my_editor;
  void *edit_baton;
  const svn_ra_reporter2_t *reporter;
  void *report_baton;

  SVN_ERR (svn_config_get_config (&config, NULL, pool));
  cfg = apr_hash_get (config, SVN_CONFIG_CATEGORY_CONFIG, APR_HASH_KEY_STRING);

  SVN_ERR (svn_cmdline_setup_auth_baton (&ab, FALSE, NULL, NULL, NULL, FALSE,
                                         cfg, NULL, NULL, pool));
  SVN_ERR (svn_ra_create_callbacks (&callbacks, pool));
  callbacks->open_tmp_file = open_tmp_file;
  callbacks->auth_baton = ab;

  SVN_ERR (svn_ra_open2 (&ra_dest, dest_url, callbacks, NULL, config, pool));
  SVN_ERR (svn_ra_open2 (&ra_src, src_url, callbacks, NULL, config, pool));

  SVN_ERR (svn_ra_get_commit_editor2 (ra_dest, &editor, &edit_baton,
                                      "Hello World!", my_commit_callback,
                                      NULL, NULL, TRUE, pool));

  /* Create a copy of the editor so we can hook some calls. */
  my_editor = apr_palloc (pool, sizeof (*my_editor));
  *my_editor = *editor;

  /* Install the editor hooks. */
  old_change_file_prop = editor->change_file_prop;
  my_editor->change_file_prop = new_change_file_prop;
  old_change_dir_prop = editor->change_dir_prop;
  my_editor->change_dir_prop = new_change_dir_prop;

  SVN_ERR (svn_ra_do_diff (ra_src, &reporter, &report_baton,
                           end_rev, "", TRUE, TRUE, src_url,
                           my_editor, edit_baton, pool));
  SVN_ERR (reporter->set_path (report_baton, "", start_rev, 0, NULL, pool));
  SVN_ERR (reporter->finish_report (report_baton, pool));

  return SVN_NO_ERROR;
}


/* Version compatibility check */
static svn_error_t *
check_lib_versions (void)
{
  static const svn_version_checklist_t checklist[] =
    {
      { "svn_subr",   svn_subr_version },
      { "svn_delta",  svn_delta_version },
      { "svn_ra",     svn_ra_version },
      { NULL, NULL }
    };

  SVN_VERSION_DEFINE (my_version);
  return svn_ver_check_list (&my_version, checklist);
}


int
main (int argc, char *argv[])
{
  apr_pool_t *pool;
  svn_error_t *error = NULL;
  int start_rev, end_rev;
  char *src_url, *dest_url;

  if (svn_cmdline_init ("svn-push", stderr) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  if (argc != 5 ||
      strcmp (argv[1], "-r") != 0 ||
      sscanf (argv[2], "%i:%i", &start_rev, &end_rev) != 2)
    {
      fprintf(stderr, "%s", "Usage : svn-push -r N:M SRC_URL DEST_URL\n");
      return EXIT_FAILURE;
    }

  src_url = argv[3];
  dest_url = argv[4];

  pool = svn_pool_create (NULL);

  /* Check library versions */
  error = check_lib_versions ();
  if (error) goto error;

  error = do_job (src_url, dest_url, start_rev, end_rev, pool);
  if (error) goto error;

  svn_pool_destroy (pool);
  return EXIT_SUCCESS;

error:
  svn_handle_error2 (error, stderr, FALSE, "svn-push: ");
  return EXIT_FAILURE;
}
