#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
                     

#include "shared_util.h"
#include "shared_file_util.h"
#include "shared_cs_util.h"


void
copy_file (const char *source_file, const char *dest_file)
{
#define CHUNKSIZE 8192

  FILE *source_fp, *dest_fp;

  struct stat buf;
  int bytes_read;
  int bytes_left;
  char buffer[CHUNKSIZE];

  if (stat (source_file, &buf))
    cs_critical_error (ERR_STAT_FAILED, source_file);

  source_fp = fopen (source_file, "r");
  if (!source_fp)
    cs_critical_error (ERR_FOPEN_READ_FAILED, source_file);

  dest_fp = fopen (dest_file, "w");
  if (!dest_fp)
    cs_critical_error (ERR_FOPEN_WRITE_FAILED, dest_file);

  bytes_left = buf.st_size;
  bytes_read = CHUNKSIZE;
  while (bytes_left)
    {
      if (bytes_left < CHUNKSIZE)
	bytes_read = bytes_left;
      if (fread (buffer, bytes_read, 1, source_fp) != 1)
	cs_critical_error (ERR_FREAD_FAILED, source_file);
      bytes_left -= bytes_read;
      if (fwrite (buffer, bytes_read, 1, dest_fp) != 1)
	cs_critical_error (ERR_FWRITE_FAILED, dest_file);
    }
  fclose (source_fp);
  fclose (dest_fp);


#undef CHUNKSIZE
}




/* next should be fixed, since it uses an arbitrarily long maximum path
** should consider using a simple cp -a source dest system() call 
*/

void
copy_dir (const char *source_base,
	  const char *dest_base,
	  const char *source_dirname, const char *dest_dirname)
{
#define LARGE_PATH 2000

  DIR *dir_p;
  struct dirent *dir_entry_p;
  char source_path[LARGE_PATH + 1],	/* full path to the directory we are copying from */
         dest_path[LARGE_PATH + 1];	/* full path to the directory we are copying to */
  char new_source_base[LARGE_PATH + 1],	/* source directory path for recursive call */
         new_dest_base[LARGE_PATH + 1];	/* dest directory path for recursive call */
  char source_file_path[LARGE_PATH + 1],	/* source file to be copied via copy_file() */
       dest_file_path[LARGE_PATH + 1];	/* dest file to be copied via copy_file() */


  snprintf (source_path, LARGE_PATH + 1, "%s%s", source_base, source_dirname);


  snprintf (dest_path, LARGE_PATH + 1, "%s%s", dest_base, dest_dirname);
  unlink(dest_path);  /* since a zero length file of that name has been created by caller */
  if (mkdir (dest_path, 0777))
    cs_critical_error (ERR_MKDIR_FAILED, dest_path);


  dir_p = opendir (source_path);

  if (!dir_p)
    cs_critical_error (ERR_OPENDIR_FAILED, source_path);
  while (NULL != (dir_entry_p = readdir (dir_p)))
    {
      if (!isdirectory (source_path, dir_entry_p->d_name))    /* shared_file_util.c */
	{
	  snprintf (source_file_path, LARGE_PATH + 1, "%s/%s", source_path,
		    dir_entry_p->d_name);
	  snprintf (dest_file_path, LARGE_PATH + 1, "%s/%s", dest_path,
		    dir_entry_p->d_name);
	  copy_file (source_file_path, dest_file_path);
	}
      else
	{
	  if (strcmp (dir_entry_p->d_name, ".")
	      && strcmp (dir_entry_p->d_name, ".."))
	    {
	      snprintf (new_source_base, LARGE_PATH + 1, "%s/", source_path);
	      snprintf (new_dest_base, LARGE_PATH + 1, "%s/", dest_path);
	      copy_dir (new_source_base, new_dest_base,
			dir_entry_p->d_name, dir_entry_p->d_name);
	    }
	}
    }

#undef LARGE_PATH
}

