/**
 * @file file_manip.cpp
 * Useful file management helpers
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Philippe Elie
 * @author John Levon
 */

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <utime.h>
#include <limits.h>
#include <stdlib.h>

#include <cstdio>
#include <cerrno>
#include <iostream>
#include <fstream>
#include <vector>

#include "op_file.h"

#include "file_manip.h"
#include "string_manip.h"

using namespace std;


bool copy_file(string const & source, string const & destination)
{
	struct stat buf;
	if (stat(source.c_str(), &buf))
		return false;

	if (!op_file_readable(source))
		return false;

	ifstream in(source.c_str());
	if (!in)
		return false;

	mode_t mode = buf.st_mode & ~S_IFMT;
	if (!(mode & S_IWUSR))
		mode |= S_IWUSR;

	int fd = open(destination.c_str(), O_RDWR|O_CREAT, mode);
	if (fd < 0)
		return false;
	close(fd);


	// ignore error here: a simple user can copy a root.root 744 file
	// but can't chown the copied file to root.

	// a scope to ensure out is closed before changing is mtime/atime
	{
	ofstream out(destination.c_str(), ios::trunc);
	if (!out)
		return false;
	out << in.rdbuf();
	}

	struct utimbuf utim;
	utim.actime = buf.st_atime;
	utim.modtime = buf.st_mtime;
	if (utime(destination.c_str(), &utim))
		return false;

	return true;
}


bool is_directory(string const & dirname)
{
	struct stat st;
	return !stat(dirname.c_str(), &st) && S_ISDIR(st.st_mode);
}


bool is_files_identical(string const & file1, string const & file2)
{
	struct stat st1;
	struct stat st2;

	if (stat(file1.c_str(), &st1) == 0 && stat(file2.c_str(), &st2) == 0) {
		if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
			return true;
	}

	return false;
}


string const op_realpath(string const & name)
{
	static char tmp[PATH_MAX];
	if (!realpath(name.c_str(), tmp))
		return name;
	return string(tmp);
}


bool op_file_readable(string const & file)
{
	return op_file_readable(file.c_str());
}

static void get_pathname(const char * pathname, void * name_list)
{
	list<string> * file_list = (list<string> *)name_list;
	file_list->push_back(pathname);
}

bool create_file_list(list<string> & file_list, string const & base_dir,
		      string const & filter, bool recursive)
{
	return !get_matching_pathnames(&file_list, get_pathname,
				       base_dir.c_str(), filter.c_str(),
				       recursive ? MATCH_ANY_ENTRY_RECURSION :
				       NO_RECURSION) ? true : false;
 
}


/**
 * @param path_name the path where we remove trailing '/'
 *
 * erase all trailing '/' in path_name except if the last '/' is at pos 0
 */
static string erase_trailing_path_separator(string const & path_name)
{
	string result(path_name);

	while (result.length() > 1) {
		if (result[result.length() - 1] != '/')
			break;
		result.erase(result.length() - 1, 1);
	}

	return result;
}

string op_dirname(string const & file_name)
{
	string result = erase_trailing_path_separator(file_name);
	if (result.find_first_of('/') == string::npos)
		return "."; 	 
  	 
	// catch result == "/" 	 
	if (result.length() == 1) 	 
		return result;

	size_t pos = result.find_last_of('/'); 	 

	// "/usr" must return "/" 	 
	if (pos == 0) 	 
		pos = 1; 	 

	result.erase(pos, result.length() - pos); 	 

	// "////usr" must return "/"
	return erase_trailing_path_separator(result);
}


string op_basename(string const & path_name)
{
	string result = erase_trailing_path_separator(path_name);

	// catch result == "/"
	if (result.length() == 1)
		return result;

	return erase_to_last_of(result, '/');
}
