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

#include "hackerlab/os/stdlib.h"
#include "hackerlab/os/errno.h"
#include "hackerlab/bugs/panic.h"
#include "hackerlab/char/str.h"
#include "hackerlab/fs/file-names.h"
#include "hackerlab/fs/cwd.h"
#include "hackerlab/vu/safe.h"
#include "file-utils/libfsutils/ensure-dir.h"
#include "file-utils/libfsutils/read-line.h"
#include "file-utils/libarch/namespace.h"
#include "file-utils/libarch/my.h"



t_uchar * 
arch_my_arch_params (void)
{
  t_uchar * home;
  t_uchar * answer;

  home = getenv ("HOME");

  invariant (!!home);
  answer = file_name_in_vicinity (0, home, ".arch-params");

  return answer;
}


static t_uchar * my_id = 0;

t_uchar *
arch_my_id_file (void)
{
  t_uchar * params_dir;
  t_uchar * id_file;

  params_dir = arch_my_arch_params ();
  id_file = file_name_in_vicinity (0, params_dir, "=id");
  lim_free (0, params_dir);

  return id_file;
}



void
arch_set_my_id (t_uchar * id)
{
  t_uchar * id_file;
  t_uchar * id_dir;
  int out_fd;

  if (my_id)
    lim_free (0, my_id);

  invariant (arch_valid_id (id));

  id_file = arch_my_id_file ();

  id_dir = file_name_directory (0, id_file);
  ensure_directory_exists (id_dir);
  lim_free (0, id_dir);

  out_fd = safe_open (id_file, O_WRONLY | O_CREAT, 0777);
  safe_ftruncate (out_fd, 0L);
  safe_printfmt (out_fd, "%s\n", id);
  safe_close (out_fd);
  lim_free (0, id_file);

  my_id = str_save (0, id);
}


t_uchar *
arch_my_id (void)
{
  t_uchar * id_file;
  int in_fd;
  t_uchar * id_contents;
  size_t len;
  t_uchar * eoid;

  if (my_id)
    return str_save (0, my_id);
  
  id_file = arch_my_id_file ();
  in_fd = safe_open (id_file, O_RDONLY, 0);
  lim_free (0, id_file);

  id_contents = 0;
  len = 0;
  safe_file_to_string (&id_contents, &len, in_fd);

  eoid = str_chr_index_n (id_contents, len, '\n');
  if (!eoid)
    eoid = id_contents + len;

  my_id = str_save_n (0, id_contents, eoid - id_contents);

  lim_free (0, id_contents);

  return str_save (0, my_id);
}

t_uchar *
arch_my_id_uid (void)
{
  t_uchar * id = 0;
  t_uchar * lb;
  t_uchar * rb;
  t_uchar * answer = 0;

  id = arch_my_id ();
  if (!id)
    return 0;

  lb = str_chr_rindex (id, '<');
  rb = str_chr_rindex (id, '>');

  invariant (lb && rb && ((lb + 1) < rb));

  answer = str_save_n (0, (lb + 1), rb - (lb + 1));

  lim_free (0, id);

  return answer;
}



static t_uchar * my_home_archive = 0;

t_uchar * 
arch_my_default_archive (t_uchar * default_archive)
{
  t_uchar * params_dir;
  t_uchar * default_archive_file;
  int in_fd;
  t_uchar * default_archive_file_contents;
  size_t archive_contents_len;
  t_uchar * nl_pos;
  t_uchar * answer;

  /* This does away with the arch conventions of using $ARCHIVE
   * and has no support for -R
   */

  if (default_archive)
    {
      if (!arch_valid_archive_name (default_archive))
        {
          safe_printfmt (2, "invalid archive name %s\n", default_archive);
          exit (2);
        }
      return str_save (0, default_archive);
    }

  if (my_home_archive)
    return str_save (0, my_home_archive);

  
  params_dir = arch_my_arch_params ();
  default_archive_file = file_name_in_vicinity (0, params_dir, "=default-archive");

  in_fd = safe_open (default_archive_file, O_RDONLY, 0);
  
  safe_file_to_string (&default_archive_file_contents, &archive_contents_len, in_fd);

  nl_pos = str_chr_index_n (default_archive_file_contents, archive_contents_len, '\n');
  if (!nl_pos)
    nl_pos = default_archive_file_contents + archive_contents_len;

  answer = str_save_n (0, default_archive_file_contents, nl_pos - default_archive_file_contents);

  lim_free (0, default_archive_file_contents);
  lim_free (0, default_archive_file);
  lim_free (0, params_dir);

  my_home_archive = str_save (0, answer);

  return answer;
}



void
arch_set_my_default_archive (t_uchar * archive)
{
  t_uchar * arch_params_dir;
  t_uchar * default_archive_file;
  int out_fd;

  invariant (arch_valid_archive_name (archive));

  if (my_home_archive)
    {
      lim_free (0, my_home_archive);
      my_home_archive = 0;
    }

  arch_params_dir = arch_my_arch_params ();
  default_archive_file = file_name_in_vicinity (0, arch_params_dir, "=default-archive");

  ensure_directory_exists (arch_params_dir);
  out_fd = safe_open (default_archive_file, O_WRONLY | O_CREAT, 0777);

  safe_ftruncate (out_fd, (long)0);
  safe_write_retry (out_fd, archive, str_length (archive));
  safe_close (out_fd);

  lim_free (0, arch_params_dir);
  lim_free (0, default_archive_file);

  my_home_archive = str_save (0, archive);
}


void
arch_delete_my_default_archive (void)
{
  t_uchar * params_dir;
  t_uchar * default_archive_file;
  int errn;

  if (my_home_archive)
    {
      lim_free (0, my_home_archive);
      my_home_archive = 0;
    }

  params_dir = arch_my_arch_params ();
  default_archive_file = file_name_in_vicinity (0, params_dir, "=default-archive");

  if (vu_unlink (&errn, default_archive_file) && (errn != ENOENT))
    {
      panic ("unable to delete ~/.arch-params/=default-archive");
    }

  lim_free (0, params_dir);
  lim_free (0, default_archive_file);
}


t_uchar *
arch_my_archive_locations_dir (void)
{
  t_uchar * arch_params_path = 0;
  t_uchar * answer = 0;

  arch_params_path = arch_my_arch_params ();
  answer = file_name_in_vicinity (0, arch_params_path, "=locations");

  lim_free (0, arch_params_path);
  return answer;
}

t_uchar *
arch_my_default_library_file (void)
{
  t_uchar * params_dir;
  t_uchar * lib_file;

  params_dir = arch_my_arch_params ();
  lib_file = file_name_in_vicinity (0, params_dir, "=revision-library");

  lim_free (0, params_dir);

  return lib_file;
}


void
arch_set_my_default_library (t_uchar * dir_spec)
{
  int here_fd;
  t_uchar * dir = 0;
  t_uchar * lib_file = 0;
  t_uchar * lib_dir = 0;
  int out_fd;

  here_fd = safe_open (".", O_RDONLY, 0);
  safe_chdir (dir_spec);
  dir = safe_current_working_directory ();

  lib_file = arch_my_default_library_file ();
  lib_dir = file_name_directory (0, lib_file);

  ensure_directory_exists (lib_dir);

  out_fd = safe_open (lib_file, O_WRONLY | O_CREAT, 0777);
  safe_ftruncate (out_fd, 0L);
  safe_printfmt (out_fd, "%s\n", dir);
  safe_close (out_fd);

  safe_fchdir (here_fd);
  safe_close (here_fd);
  lim_free (0, dir);
  lim_free (0, lib_file);
  lim_free (0, lib_dir);
}


t_uchar *
arch_my_default_library (void)
{
  t_uchar * lib_file = 0;
  t_uchar * answer = 0;

  lib_file = arch_my_default_library_file ();

  if (!safe_access (lib_file, F_OK))
    {
      answer = read_line_from_file (lib_file);
    }
  else
    answer = 0;

  lim_free (0, lib_file);

  return answer;
}


void
arch_delete_my_default_library (void)
{
  t_uchar * lib_file = 0;

  lib_file = arch_my_default_library_file ();

  if (!safe_access (lib_file, F_OK))
    safe_unlink (lib_file);

  lim_free (0, lib_file);
}






/* tag: Tom Lord Mon May 12 15:01:17 2003 (my.c)
 */
