/* undo.c:
 *
 * vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2
 ****************************************************************
 * Copyright (C) 2003 Tom Lord
 *
 * See the file "COPYING" for further information about
 * the copyright and warranty status of this work.
 */


#include "hackerlab/bugs/exception.h"
#include "hackerlab/char/str.h"
#include "hackerlab/char/char-class.h"
#include "hackerlab/fmt/cvt.h"
#include "hackerlab/fs/file-names.h"
#include "hackerlab/vu/safe.h"
#include "libfsutils/dir-listing.h"
#include "libfsutils/rmrf.h"
#include "libarch/conflict-handling.h"
#include "libarch/make-changeset.h"
#include "libarch/make-changeset-files.h"
#include "libarch/apply-changeset.h"
#include "libarch/chatter.h"
#include "libarch/undo.h"


/* __STDC__ prototypes for static functions */


void
arch_undo (int chatter_fd, t_uchar * dest_dir, int delete_changeset, arch_project_tree_t * tree,
           arch_project_tree_t * baseline_tree, rel_table file_list, assoc_table inode_shortcut, int forward,   int escape_classes)
{
  struct arch_make_changeset_report make_report = {0, };
  struct arch_apply_changeset_report * apply_report;
  arch_apply_changeset_report_callback apply_report_callback = NULL;
  void * apply_report_thunk = NULL;

  if (!file_list)
    arch_make_changeset (&make_report, baseline_tree, tree, dest_dir, arch_unspecified_id_tagging, arch_inventory_unrecognized, 0, inode_shortcut, 0, escape_classes);
  else
    arch_make_files_changeset (&make_report, dest_dir, file_list, baseline_tree, tree, arch_unspecified_id_tagging, arch_inventory_unrecognized, escape_classes);
   	  
  arch_chatter (chatter_fd, "* reverting changes\n");
  if (chatter_fd >= 0)
    {
      apply_report_callback = apply_print_callback;
      apply_report_thunk = (void *)(long)chatter_fd;
    }

  apply_report = arch_apply_changeset (dest_dir, talloc_context, tree, arch_unspecified_id_tagging, arch_inventory_unrecognized, 1, forward, escape_classes, apply_report_callback, apply_report_thunk);

  if (delete_changeset)
    rmrf_file (dest_dir);

  /* FIXME rbc 20050203 FIXME resolve conflicts on the files in file_list 
   * this wants a rel_table taking resolved-specific-files call for ease.
   */
  if (!file_list)
      arch_tree_clear_conflicts (tree);

  talloc_free (apply_report);
}

t_uchar *
arch_latest_undo_changeset (t_ulong * level_n, t_uchar * tree_root)
{
  rel_table files = 0;
  t_uchar * answer = 0;
  t_ulong latest_n = 0;
  int x;

  files = directory_files (tree_root);

  for (x = 0; x < rel_n_records (files); ++x)
    {
      if (!str_cmp_prefix (",,undo-", files[x][0]))
        {
          int ign;
          t_uchar * pos;
          t_ulong this_n;

          for (pos = files[x][0] + sizeof (",,undo-") - 1; char_is_digit (*pos); ++pos)
            ;

          if (*pos)
            continue;

          pos = files[x][0] + sizeof (",,undo-") - 1;
          if (cvt_decimal_to_ulong (&ign, &this_n, pos, str_length (pos)))
            continue;

          if (this_n >= latest_n)
            {
              lim_free (0, answer);
              answer = file_name_in_vicinity (0, tree_root, files[x][0]);
              if (level_n)
                *level_n = this_n;

              latest_n = this_n;
            }
        }
    }

  rel_free_table (files);
  return answer;
}

t_uchar *
arch_next_undo_changeset (t_ulong * level_n, t_uchar * tree_root)
{
  t_uchar * prev = 0;
  t_ulong prev_n;
  t_uchar * this = 0;
  t_uchar * answer = 0;

  prev = arch_latest_undo_changeset (&prev_n, tree_root);

  if (!prev)
    {
      if (level_n)
        *level_n = 1;
      this = str_save (0, ",,undo-1");
    }
  else
    {
      t_uchar buf[64];

      cvt_ulong_to_decimal (buf, prev_n + 1);
      this = str_alloc_cat (0, ",,undo-", buf);
    }

  answer = file_name_in_vicinity (0, tree_root, this);

  lim_free (0, prev);
  lim_free (0, this);
  return answer;
}



/* tag: Tom Lord Thu May 29 14:20:31 2003 (undo.c)
 */


syntax highlighted by Code2HTML, v. 0.9.1