/*
 * Copyright 2009 Funambol, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

#include "FileSystemUtils.h"

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

#include "Logger/Logger.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 = stPath.substr(0, stPath.length() - tReplaceLen);
			stPath += 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] != c_pathSeparator)
        {
            full_path = full_path + c_pathSeparatorStr;
        }
        res = DeleteDirectoryByPath(full_path);
    }
    else
    {
        res = true;
        RemoveDirectoryA(path.c_str());
    }
    return res;
}

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

bool CreatePath(const char* path, NS_Logging::Logger* logger)
{
    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_pathSeparatorStr, 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;
}

}
