/* tree-root.c
 *
 ****************************************************************
 * Copyright (C) 2003 Tom Lord
 * 
 * See the file "COPYING" for further information about
 * the copyright and warranty status of this work.
 */


#include "config-options.h"
#include "hackerlab/cmd/main.h"
#include "file-utils/libarch/project-tree.h"



static t_uchar * program_name = "tree-root";
static t_uchar * usage = "[options] [dir]";
static t_uchar * version_string = (cfg__std__package " from regexps.com\n"
				   "\n"
				   "Copyright 2003 Tom Lord\n"
				   "\n"
				   "This is free software; see the source for copying conditions.\n"
				   "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"
				   "PARTICULAR PURPOSE.\n"
				   "\n"
				   "Report bugs to " cfg__file_utils_bug_mail ".\n"
				   "\n");

#define OPTS(OP, OP2) \
  OP (opt_help_msg, "h", "help", 0, \
      "Display a help message and exit.") \
  OP (opt_long_help, "H", 0, 0, \
      "Display a verbose help message and exit.") \
  OP (opt_version, "V", "version", 0, \
      "Display a release identifier string") \
  OP2 (opt_version, 0, 0, 0, "and exit.") \
  OP (opt_accurate, 0, "accurate", 0, \
      "error for mid-txn trees") \
  OP (opt_silent, "s", "silent", 0, \
      "exit status only")

static t_uchar long_help[] = ("find and print the root of a project tree\n");

enum options
{
  OPTS (OPT_ENUM, OPT_IGN)  
};

struct opt_desc opts[] = 
{
  OPTS (OPT_DESC, OPT_DESC)
    {-1, 0, 0, 0, 0}
};



int
main (int argc, char * argv[])
{
  int o;
  struct opt_parsed * option;
  int silent;
  int accurate;
  char * dir;
  t_uchar * result;
  enum arch_tree_state tree_state;
  int status;

  silent = 0;
  accurate = 0;

  safe_buffer_fd (1, 0, O_WRONLY, 0);

  option = 0;

  while (1)
    {
      o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv, program_name, usage, version_string, long_help, opt_help_msg, opt_long_help, opt_version);
      if (o == opt_none)
	break;
      switch (o)
	{
	default:
	  safe_printfmt (2, "unhandled option `%s'\n", option->opt_string);
	  panic ("internal error parsing arguments");

	usage_error:
	  opt_usage (2, argv[0], program_name, usage, 1);
	  exit (1);

          /* bogus_arg: */
	  safe_printfmt (2, "ill-formed argument for `%s' (`%s')\n", option->opt_string, option->arg_string);
	  goto usage_error;


        case opt_silent:
          {
            silent = 1;
            break;
          }

        case opt_accurate:
          {
            accurate = 1;
            break;
          }
	}
    }

  if (argc > 2)
    goto usage_error;

  if (argc == 1)
    dir = 0;
  else
    dir = argv[1];
  
  result = arch_tree_root (&tree_state, (t_uchar *)dir, accurate);

  if (!result)
    {
      status = 1;
      if (!silent)
        safe_printfmt (2, "tree-root: not in a project tree\n  dir: %s\n", (dir ? dir : "."));
    }
  else if (!accurate || (tree_state == arch_tree_in_ok_state))
    {
      status = 0;
      if (!silent)
        safe_printfmt (1, "%s\n", result);
    }
  else
    {
      /* in a project tree, but not in an ok state, --accurate specified
       * 
       * --silent doesn't supress these error messages.
       */

      status = 1;
      switch (tree_state)
        {
        default:
          panic ("unknown project tree state");
          break;

        case arch_tree_in_resolve_conflicts:
          {
            safe_printfmt (2, "tree-root: project tree in mid-merge\n  dir: %s\n  project tree %s\n",
                           (dir ? dir : "."),
                           result);
            break;
          }

        case arch_tree_in_commit_definite:
        case arch_tree_in_mid_commit:
          {
            safe_printfmt (2, "tree-root: project tree in mid-commit\n  dir: %s\n  project tree %s\n",
                           (dir ? dir : "."),
                           result);

            /* The larch version just implicitly repairs the tree for 
             * arch_tree_in_commit_definite.   This vesion should too,
             * eventually.
             */
            break;
          }
        }
    }


  exit (status);
  return 0;
}




/* tag: Tom Lord Mon May 12 12:25:44 2003 (tree-root.c)
 */
