/*
 * node_tree.c:  an editor for tracking repository deltas changes
 *
 * ====================================================================
 * 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 <stdio.h>
#define APR_WANT_STRFUNC
#include <apr_want.h>
#include "apr_pools.h"
#include "svn_types.h"
#include "svn_error.h"
#include "svn_path.h"
#include "svn_delta.h"
#include "svn_fs.h"
#include "svn_repos.h"
#include "repos.h"


/*** Node creation and assembly structures and routines. ***/
static svn_repos_node_t *
create_node (const char *name, 
             apr_pool_t *pool)
{
  svn_repos_node_t *node = apr_pcalloc (pool, sizeof (svn_repos_node_t));
  node->action = 'R';
  node->kind = svn_node_unknown;
  node->name = apr_pstrdup (pool, name);
  return node;
}


static svn_repos_node_t *
create_sibling_node (svn_repos_node_t *elder, 
                     const char *name, 
                     apr_pool_t *pool)
{
  svn_repos_node_t *tmp_node;
  
  /* No ELDER sibling?  That's just not gonna work out. */
  if (! elder)
    return NULL;

  /* Run to the end of the list of siblings of ELDER. */
  tmp_node = elder;
  while (tmp_node->sibling)
    tmp_node = tmp_node->sibling;

  /* Create a new youngest sibling and return that. */
  return (tmp_node->sibling = create_node (name, pool));
}


static svn_repos_node_t *
create_child_node (svn_repos_node_t *parent, 
                   const char *name, 
                   apr_pool_t *pool)
{
  /* No PARENT node?  That's just not gonna work out. */
  if (! parent)
    return NULL;

  /* If PARENT has no children, create its first one and return that. */
  if (! parent->child)
    return (parent->child = create_node (name, pool));

  /* If PARENT already has a child, create a new sibling for its first
     child and return that. */
  return create_sibling_node (parent->child, name, pool);
}


static svn_repos_node_t *
find_child_by_name (svn_repos_node_t *parent, 
                    const char *name)
{
  svn_repos_node_t *tmp_node;

  /* No PARENT node, or a barren PARENT?  Nothing to find. */
  if ((! parent) || (! parent->child))
    return NULL;

  /* Look through the children for a node with a matching name. */
  tmp_node = parent->child;
  while (1)
    {
      if (! strcmp (tmp_node->name, name))
        {
          return tmp_node;
        }
      else
        {
          if (tmp_node->sibling)
            tmp_node = tmp_node->sibling;
          else
            break;
        }
    }

  return NULL;
}


/*** Editor functions and batons. ***/

struct edit_baton
{
  svn_fs_t *fs;
  svn_fs_root_t *root;
  svn_fs_root_t *base_root;
  apr_pool_t *pool;
  apr_pool_t *node_pool;
  svn_repos_node_t *node;
};


struct dir_baton
{
  svn_stringbuf_t *path;
  struct edit_baton *edit_baton;
  svn_repos_node_t *node;
};


struct file_baton
{
  svn_stringbuf_t *path;
  struct dir_baton *dir_baton;
  svn_repos_node_t *node;
};


struct window_handler_baton
{
  svn_repos_node_t *node;
};


static svn_error_t *
delete_entry (svn_stringbuf_t *name, 
              svn_revnum_t revision,
              void *parent_baton)
{
  struct dir_baton *d = (struct dir_baton *) parent_baton;
  struct edit_baton *eb = (struct edit_baton *) d->edit_baton;
  svn_stringbuf_t *full_path;
  svn_repos_node_t *node;
  int is_dir;

  /* Construct the full path of this entry based on its parent. */
  full_path = svn_stringbuf_dup (d->path, eb->pool);
  svn_path_add_component (full_path, name);

  /* Was this a dir or file (we have to check the base root for this one) */
  SVN_ERR (svn_fs_is_dir (&is_dir, eb->base_root, full_path->data, eb->pool));

  /* Get (or create) the change node and update it. */
  node = find_child_by_name (d->node, name->data);
  if (! node)
    node = create_child_node (d->node, name->data, eb->node_pool);

  if (is_dir)
    node->kind = svn_node_dir;
  else
    node->kind = svn_node_file;

  node->action = 'D';
  return SVN_NO_ERROR;
}


static svn_error_t *
open_root (void *edit_baton,
              svn_revnum_t base_revision,
              void **root_baton)
{
  struct edit_baton *eb = (struct edit_baton *) edit_baton;
  struct dir_baton *d = apr_pcalloc (eb->pool, sizeof (*d));

  d->path = (svn_stringbuf_t *) svn_stringbuf_create ("", eb->pool);
  d->edit_baton = eb;
  d->node = (eb->node = create_node ("", eb->node_pool));
  d->node->kind = svn_node_dir;
  d->node->action = 'R';
  *root_baton = d;
  
  return SVN_NO_ERROR;
}


static svn_error_t *
open_directory (svn_stringbuf_t *name,
                   void *parent_baton,
                   svn_revnum_t base_revision,
                   void **child_baton)
{
  struct dir_baton *pd = (struct dir_baton *) parent_baton;
  struct edit_baton *eb = (struct edit_baton *) pd->edit_baton;
  struct dir_baton *d = apr_pcalloc (pd->edit_baton->pool, sizeof (*d));

  /* Construct the full path of the new directory */
  d->path = svn_stringbuf_dup (pd->path, eb->pool);
  svn_path_add_component (d->path, name);

  /* Fill in other baton members */
  d->edit_baton = eb;
  d->node = create_child_node (pd->node, name->data, eb->node_pool);
  d->node->kind = svn_node_dir;
  d->node->action = 'R';
  *child_baton = d;

  return SVN_NO_ERROR;
}


static svn_error_t *
add_directory (svn_stringbuf_t *name,
               void *parent_baton,
               svn_stringbuf_t *copyfrom_path,
               svn_revnum_t copyfrom_revision,
               void **child_baton)
{
  struct dir_baton *pd = (struct dir_baton *) parent_baton;
  struct edit_baton *eb = (struct edit_baton *) pd->edit_baton;
  struct dir_baton *d = apr_pcalloc (pd->edit_baton->pool, sizeof (*d));

  /* Construct the full path of the new directory */
  d->path = svn_stringbuf_dup (pd->path, eb->pool);
  svn_path_add_component (d->path, name);

  /* Fill in other baton members */
  d->edit_baton = eb;
  d->node = create_child_node (pd->node, name->data, eb->node_pool);
  d->node->kind = svn_node_dir;
  d->node->action = 'A';
  *child_baton = d;

  return SVN_NO_ERROR;
}


static svn_error_t *
open_file (svn_stringbuf_t *name,
              void *parent_baton,
              svn_revnum_t base_revision,
              void **file_baton)
{
  struct dir_baton *pd = (struct dir_baton *) parent_baton;
  struct edit_baton *eb = (struct edit_baton *) pd->edit_baton;
  struct file_baton *fb = apr_pcalloc (pd->edit_baton->pool, sizeof (*fb));

  /* Construct the full path of the new directory */
  fb->path = svn_stringbuf_dup (pd->path, eb->pool);
  svn_path_add_component (fb->path, name);

  /* Fill in other baton members */
  fb->dir_baton = pd;
  fb->node = create_child_node (pd->node, name->data, eb->node_pool);
  fb->node->kind = svn_node_file;
  fb->node->action = 'R';
  *file_baton = fb;

  return SVN_NO_ERROR;
}


static svn_error_t *
add_file (svn_stringbuf_t *name,
          void *parent_baton,
          svn_stringbuf_t *copyfrom_path,
          svn_revnum_t copyfrom_revision,
          void **file_baton)
{
  struct dir_baton *pd = (struct dir_baton *) parent_baton;
  struct edit_baton *eb = (struct edit_baton *) pd->edit_baton;
  struct file_baton *fb = apr_pcalloc (pd->edit_baton->pool, sizeof (*fb));

  /* Construct the full path of the new directory */
  fb->path = svn_stringbuf_dup (pd->path, eb->pool);
  svn_path_add_component (fb->path, name);

  /* Fill in other baton members */
  fb->dir_baton = pd;
  fb->node = create_child_node (pd->node, name->data, eb->node_pool);
  fb->node->kind = svn_node_file;
  fb->node->action = 'A';
  *file_baton = fb;

  return SVN_NO_ERROR;
}


static svn_error_t *
window_handler (svn_txdelta_window_t *window, void *baton)
{
  return SVN_NO_ERROR;
}


static svn_error_t *
apply_textdelta (void *file_baton, 
                 svn_txdelta_window_handler_t *handler,
                 void **handler_baton)
{
  struct file_baton *fb = (struct file_baton *) file_baton;
  struct edit_baton *eb = (struct edit_baton *) fb->dir_baton->edit_baton;
  struct window_handler_baton *whb = apr_palloc (eb->pool, sizeof (*whb));

  whb->node = fb->node;
  whb->node->text_mod = TRUE;
  *handler = window_handler;
  *handler_baton = whb;

  return SVN_NO_ERROR;
}



static svn_error_t *
change_file_prop (void *file_baton,
                  svn_stringbuf_t *name, 
                  svn_stringbuf_t *value)
{
  struct file_baton *fb = (struct file_baton *) file_baton;
  fb->node->prop_mod = TRUE;

  return SVN_NO_ERROR;
}


static svn_error_t *
change_dir_prop (void *parent_baton,
                 svn_stringbuf_t *name, 
                 svn_stringbuf_t *value)
{
  struct dir_baton *d = (struct dir_baton *) parent_baton;
  d->node->prop_mod = TRUE;

  return SVN_NO_ERROR;
}


svn_error_t *
svn_repos_node_editor (const svn_delta_edit_fns_t **editor,
                       void **edit_baton,
                       svn_repos_t *repos,
                       svn_fs_root_t *base_root,
                       svn_fs_root_t *root,
                       apr_pool_t *node_pool,
                       apr_pool_t *pool)
{
  svn_delta_edit_fns_t *my_editor;
  struct edit_baton *my_edit_baton;

  /* Set up the editor. */
  my_editor = svn_delta_old_default_editor (pool);
  my_editor->open_root           = open_root;
  my_editor->delete_entry        = delete_entry;
  my_editor->add_directory       = add_directory;
  my_editor->open_directory      = open_directory;
  my_editor->add_file            = add_file;
  my_editor->open_file           = open_file;
  my_editor->apply_textdelta     = apply_textdelta;
  my_editor->change_file_prop    = change_file_prop;
  my_editor->change_dir_prop     = change_dir_prop;

  /* Set up the edit baton. */
  my_edit_baton = apr_pcalloc (pool, sizeof (*my_edit_baton));
  my_edit_baton->node_pool = node_pool;
  my_edit_baton->pool = pool;
  my_edit_baton->fs = repos->fs;
  my_edit_baton->root = root;
  my_edit_baton->base_root = base_root;

  *editor = my_editor;
  *edit_baton = my_edit_baton;

  return SVN_NO_ERROR;
}



svn_repos_node_t *
svn_repos_node_from_baton (void *edit_baton)
{
  struct edit_baton *eb = (struct edit_baton *) edit_baton;
  return eb->node;
}


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