//
// C++ Implementation: osutils
//
// Description:
//
//
// Author: smidl <smidl@utia.cas.cz>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include "osutils.h"
#include "bdmerror.h"
#include <iostream>
#include <stdexcept>
#include <string>

#ifdef WIN32
#include "dirent.h"
#include <direct.h>
#define rmdir _rmdir
#define unlink _unlink
#else
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif

#include <fcntl.h>
#include <errno.h>


void get_fname ( char* filename, string &dirname, string &f ) {
#ifdef WIN32
    sprintf ( filename, "%s\\%s", dirname.c_str(), f.c_str() );
#else
    sprintf ( filename, "%s/%s", dirname.c_str() , f.c_str() );
#endif
}

void makedir ( string &dirname, bool rewrite ) {
#ifdef WIN32
    if ( _mkdir ( dirname.c_str() ) == -1 )   // Create the directory
#else
    if ( mkdir ( dirname.c_str(), 00755 ) == -1 )   // Create the directory
#endif
    {
        if ( ( rewrite ) && ( errno == EEXIST ) ) bdm_warning ( "rewriting directory" );
        else bdm_error ( "dirfilelog:: cannot create directory" );
    }
}

bool remove_all ( const char *path ) {
    DIR *dir;
    dirent *de;

    bool rv = true;
    if ( ( dir = opendir ( path ) ) != 0 ) {
        try {
            std::string top ( path );
            top += "/";

            while ( ( de = readdir ( dir ) ) != 0 ) {
                if ( strcmp ( de->d_name, "." ) && strcmp ( de->d_name, ".." ) ) {
                    std::string subpath ( top );
                    subpath += de->d_name;
                    remove_all ( subpath.c_str() );
                }
            }
        } catch ( ... ) {
            closedir ( dir );
            throw;
        }

        closedir ( dir );

        if ( rmdir ( path ) ) {
            std::string msg = "can't remove dir ";
            msg += path;
            bdm_error ( msg );
        }
    } else {
        if ( ( errno == ENOTDIR ) || // Linux
                ( errno == EINVAL ) ) { // Windows
            if ( unlink ( path ) ) {
                std::string msg = "can't remove file ";
                msg += path;
                bdm_error ( msg );
            }
        } else {
            if ( errno != ENOENT ) {
                std::string msg = "can't remove ";
                msg += path;
                bdm_error ( msg );
            } else {
                // it wasn't there in the first place
                rv = false;
            }
        }
    }

    return rv;
}
