/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

/* $Id$ */

#include "FileSystemUtils.h"

#include <string>
#include <stdio.h>

namespace NS_DM_Client
{

const char* const c_privateDataExt = ".priv";
const char c_pathSeparator = '/';
const char* const c_pathSeparatorStr = "/";

bool DeleteDirectoryByPath(const String& path)
{
	BOOL fRet = FALSE;
    if(path.empty()) return false;

    size_t tReplaceLen = 1;
    WIN32_FIND_DATAA fd = {};

    String stPath = path; 
    stPath += "/*";

    HANDLE hFind = FindFirstFileA(stPath.c_str(), &fd);
    if(hFind != INVALID_HANDLE_VALUE)
    {
        fRet = TRUE;
        do {
            if(!(strcmp( fd.cFileName, ".") && strcmp( fd.cFileName, "..")))
			{
				continue;
			}

			stPath.replace( stPath.end() - tReplaceLen, stPath.end(), fd.cFileName);
            tReplaceLen = strlen( fd.cFileName);

            if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
                fRet = DeleteDirectoryByPath(stPath);
			}
			else
            {
                if( fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
				{
                    SetFileAttributesA( stPath.c_str(), FILE_ATTRIBUTE_NORMAL);
				}
				fRet = DeleteFileA(stPath.c_str());
            }
        } 
		while( fRet && FindNextFileA( hFind, &fd));
        
		FindClose( hFind);

        if( fRet) 
		{	
			fRet = RemoveDirectoryA( path.c_str());
		}
	}

	return (fRet == TRUE) ? true : false;
}

//------------------------------------------------------------------------------------------------------

bool DeleteFilesystemEntity(const String& path)
{
    bool res = false;
    
	// try delete as private data
    String entity = path + c_privateDataExt;
    if (DeleteFileA(entity.c_str()) == 0)
	{
        // if failed, try delete as directory
        String full_path = path;
        if (full_path[full_path.length()-1] != '/')
        {
            full_path = full_path + '/';
        }
        res = DeleteDirectoryByPath(full_path);
    }
    else
    {
        res = true;
        RemoveDirectoryA(path.c_str());
    }
    return res;
}

//------------------------------------------------------------------------------------------------------

bool CreatePath(const char* path)
{
    bool res = true;

    size_t pos_beg = 0;
    size_t pos_end = 0; 
    
	String full_path = path;
    if (full_path[full_path.length()-1] != c_pathSeparator)
    {
        full_path = full_path + c_pathSeparatorStr;
    }

    String FormedPath; 

    BOOL status;
    bool first_separator = true;
    while ( (pos_end = full_path.find(c_pathSeparator, pos_beg)) != String::npos )
    {
        if (first_separator)
        {
            first_separator = false;
            pos_beg = pos_end + 1;
            continue;
        }

        FormedPath = full_path.substr(0, pos_end + 1);        
		status = CreateDirectoryA(FormedPath.c_str(), NULL);
        if ((status == FALSE) && (GetLastError() != ERROR_ALREADY_EXISTS))
        {
            res = false;
            break;
        }
        pos_beg = pos_end + 1;
    } 

    return res;
}

}
