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

#include "hackerlab/bugs/panic.h"
#include "hackerlab/char/str.h"
#include "hackerlab/fs/file-names.h"
#include "hackerlab/vu/safe.h"
#include "file-utils/libfsutils/dir-listing.h"
#include "file-utils/libarch/my.h"
#include "file-utils/libarch/namespace.h"
#include "file-utils/libarch/patch-logs.h"
#include "file-utils/libarch/changeset-utils.h"
#include "file-utils/libarch/libraries.h"





t_uchar * 
arch_library_archive_dir (t_uchar * archive)
{
  t_uchar * lib_dir = 0;
  t_uchar * archive_dir = 0;
  
  lib_dir = arch_my_default_library ();
  if (!lib_dir)
    return 0;

  invariant (arch_valid_archive_name (archive));

  archive_dir = file_name_in_vicinity (0, lib_dir, archive);

  lim_free (0, lib_dir);
  return archive_dir;
}


t_uchar * 
arch_library_category_dir (t_uchar * archive, t_uchar * category)
{
  t_uchar * archive_dir = 0;
  t_uchar * cat_dir = 0;
  
  invariant (arch_valid_package_name (category, arch_no_archive, arch_req_category, 0));

  archive_dir = arch_library_archive_dir (archive);
  if (!archive_dir)
    return 0;

  cat_dir = file_name_in_vicinity (0, archive_dir, category);

  lim_free (0, archive_dir);
  return cat_dir;
}


t_uchar * 
arch_library_branch_dir (t_uchar * archive, t_uchar * branch)
{
  t_uchar * category = 0;
  t_uchar * cat_dir = 0;
  t_uchar * answer = 0;
  
  invariant (arch_valid_package_name (branch, arch_no_archive, arch_req_package, 0));

  category = arch_parse_package_name (arch_ret_category, 0, branch);

  cat_dir = arch_library_category_dir (archive, category);

  if (cat_dir)
    {
      answer = file_name_in_vicinity (0, cat_dir, branch);
    }

  lim_free (0, category);
  lim_free (0, cat_dir);
  return answer;
}


t_uchar * 
arch_library_version_dir (t_uchar * archive, t_uchar * version)
{
  t_uchar * branch = 0;
  t_uchar * branch_dir = 0;
  t_uchar * answer = 0;
  
  invariant (arch_valid_package_name (version, arch_no_archive, arch_req_version, 0));

  branch = arch_parse_package_name (arch_ret_package, 0, version);

  branch_dir = arch_library_branch_dir (archive, branch);

  if (branch_dir)
    {
      answer = file_name_in_vicinity (0, branch_dir, version);
    }

  lim_free (0, branch);
  lim_free (0, branch_dir);
  return answer;
}


t_uchar * 
arch_library_revision_dir (t_uchar * archive, t_uchar * revision)
{
  t_uchar * version = 0;
  t_uchar * version_dir = 0;
  t_uchar * answer = 0;
  
  invariant (arch_valid_package_name (revision, arch_no_archive, arch_req_patch_level, 0));

  version = arch_parse_package_name (arch_ret_package_version, 0, revision);

  version_dir = arch_library_version_dir (archive, version);

  if (version_dir)
    {
      answer = file_name_in_vicinity (0, version_dir, revision);
    }

  lim_free (0, version);
  lim_free (0, version_dir);
  return answer;
}


t_uchar * 
arch_library_find (t_uchar * archive, t_uchar * revision)
{
  t_uchar * revision_dir = 0;
  t_uchar * answer = 0;

  revision_dir = arch_library_revision_dir (archive, revision);
  
  if (revision_dir && !safe_access (revision_dir, F_OK))
    answer = str_save (0, revision_dir);
  
  lim_free (0, revision_dir);

  return answer;
}


t_uchar * 
arch_library_find_file (t_uchar * archive, t_uchar * revision, t_uchar * loc)
{
  t_uchar * revision_dir = 0;
  t_uchar * file_path = 0;

  revision_dir = arch_library_find (archive, revision);

  if (revision_dir)
    {
      file_path = file_name_in_vicinity (0, revision_dir, loc);
      
      if (safe_access (file_path, F_OK))
        {
          lim_free (0, file_path);
          file_path = 0;
        }
    }
  
  lim_free (0, revision_dir);

  return file_path;
}


t_uchar * 
arch_library_find_file_by_tag (t_uchar * archive, t_uchar * revision, t_uchar * tag)
{
  t_uchar * revision_dir = 0;
  t_uchar * file_path = 0;

  revision_dir = arch_library_find (archive, revision);

  if (revision_dir)
    {
      t_uchar * index_file = 0;
      rel_table index = 0;
      int x;

      index_file = arch_library_index_file (archive, revision);
      index = arch_read_changeset_index (index_file);

      for (x = 0; x < rel_n_records (index); ++x)
        {
          if (!str_cmp (tag, index[x][1]))
            {
              file_path = file_name_in_vicinity (0, revision_dir, index[x][0]);
              break;
            }
        }
      
      lim_free (0, index_file);
      rel_free_table (index);
    }
  
  lim_free (0, revision_dir);

  return file_path;
}


rel_table
arch_library_archives (void)
{
  t_uchar * dir = 0;
  rel_table files = 0;
  rel_table answer = 0;

  dir = arch_my_default_library ();

  if (dir)
    {
      files = directory_files (dir);
      answer = arch_pick_archives_by_field (files, 0);
    }

  lim_free (0, dir);
  rel_free_table (files);

  rel_sort_table_by_field (0, answer, 0);
  return answer;
}


rel_table
arch_library_categories (t_uchar * archive)
{
  t_uchar * dir = 0;
  rel_table files = 0;
  rel_table answer = 0;

  dir = arch_library_archive_dir (archive);

  if (dir)
    {
      files = directory_files (dir);
      answer = arch_pick_categories_by_field (files, 0);
    }

  lim_free (0, dir);
  rel_free_table (files);

  rel_sort_table_by_field (0, answer, 0);
  return answer;
}

rel_table
arch_library_branches (t_uchar * archive, t_uchar * category)
{
  t_uchar * dir = 0;
  rel_table files = 0;
  rel_table answer = 0;

  dir = arch_library_category_dir (archive, category);

  if (dir)
    {
      files = directory_files (dir);
      answer = arch_pick_branches_by_field (files, 0);
    }

  lim_free (0, dir);
  rel_free_table (files);

  rel_sort_table_by_field (0, answer, 0);
  return answer;
}


rel_table
arch_library_versions (t_uchar * archive, t_uchar * branch)
{
  t_uchar * dir = 0;
  rel_table files = 0;
  rel_table answer = 0;

  dir = arch_library_branch_dir (archive, branch);

  if (dir)
    {
      files = directory_files (dir);
      answer = arch_pick_versions_by_field (files, 0);
    }

  lim_free (0, dir);
  rel_free_table (files);

  arch_sort_table_by_name_field (0, answer, 0);
  return answer;
}

rel_table
arch_library_revisions (t_uchar * archive, t_uchar * version, int full)
{
  t_uchar * dir = 0;
  rel_table files = 0;
  rel_table answer = 0;

  dir = arch_library_version_dir (archive, version);

  if (dir)
    {
      int x;

      files = directory_files (dir);
      answer = arch_pick_revisions_by_field (files, 0);

      for (x = 0; x < rel_n_records (answer); ++x)
        {
          t_uchar * t = 0;

          t = answer[x][0];

          if (full)
            {
              answer[x][0] = arch_fully_qualify (archive, t);
            }
          else
            {
              answer[x][0] = arch_parse_package_name (arch_ret_patch_level, 0, t);
            }
          lim_free (0, t);
        }
    }

  lim_free (0, dir);
  rel_free_table (files);

  if (full)
    {
      arch_sort_table_by_name_field (0, answer, 0);
    }
  else
    {
      arch_sort_table_by_patch_level_field (0, answer, 0);
    }
  return answer;
}

t_uchar *
arch_library_log (t_uchar * archive, t_uchar * revision)
{
  t_uchar * rev_dir = 0;
  t_uchar * log_path = 0;
  int in_fd;
  t_uchar * answer = 0;
  size_t len;

  rev_dir = arch_library_revision_dir (archive, revision);
  log_path = arch_log_file (rev_dir, archive, revision);
  in_fd = safe_open (log_path, O_RDONLY, 0);
  safe_file_to_string (&answer, &len, in_fd);
  answer = lim_realloc (0, answer, len + 1);
  answer[len] = 0;
  safe_close (in_fd);

  lim_free (0, rev_dir);
  lim_free (0, log_path);
  return answer;
}


t_uchar * 
arch_library_index_file (t_uchar * archive, t_uchar * revision)
{
  t_uchar * revision_dir = 0;
  t_uchar * answer = 0;
  
  revision_dir = arch_library_revision_dir (archive, revision);
  invariant (!!revision_dir);

  answer = file_name_in_vicinity (0, revision_dir, ",,index");

  lim_free (0, revision_dir);
  return answer;
}


rel_table
arch_library_index (t_uchar * archive, t_uchar * revision)
{
  t_uchar * index_path = 0;
  rel_table answer = 0;

  index_path = arch_library_index_file (archive, revision);
  answer = arch_read_changeset_index (index_path);

  lim_free (0, index_path);
  return answer;
}





/* tag: Tom Lord Wed May 21 13:56:29 2003 (libraries.c)
 */
