/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

#ifndef _LOG4CXX_FILE_H
#define _LOG4CXX_FILE_H

#include <log4cxx/logger.h>
#include <log4cxx/logstring.h>

#if defined(_MSC_VER)
	#pragma warning ( push )
	#pragma warning ( disable: 4251 )
#endif

extern "C" {
	struct apr_file_t;
	struct apr_finfo_t;
}

namespace log4cxx
{
namespace helpers
{
class Transcoder;
class Pool;
}

/**
* An abstract representation of file and directory path names.
*/
class LOG4CXX_EXPORT File
{
	public:
		/**
		*   Construct a new instance.
		*/
		File();
		/**
		*   Construct a new instance.  Use setPath to specify path using a LogString.
		* @param path file path in local encoding.
		*/
		File(const char* path);
		/**
		*   Construct a new instance.  Use setPath to specify path using a LogString.
		* @param path file path in current encoding.
		*/
		File(const std::string& path);
#if LOG4CXX_WCHAR_T_API
		/**
		*   Construct a new instance.  Use setPath to specify path using a LogString.
		* @param path file path.
		*/
		File(const wchar_t* path);
		/**
		*   Construct a new instance.  Use setPath to specify path using a LogString.
		* @param path file path.
		*/
		File(const std::wstring& path);
#endif
#if LOG4CXX_UNICHAR_API
		/**
		*   Construct a new instance.  Use setPath to specify path using a LogString.
		* @param path file path.
		*/
		File(const UniChar* path);
		/**
		*   Construct a new instance.  Use setPath to specify path using a LogString.
		* @param path file path.
		*/
		File(const std::basic_string<UniChar>& path);
#endif
#if LOG4CXX_CFSTRING_API
		/**
		*   Construct a new instance.  Use setPath to specify path using a LogString.
		* @param path file path.
		*/
		File(const CFStringRef& path);
#endif
		/**
		 *  Copy constructor.
		 */
		File(const File& src);
		/**
		 *  Assignment operator.
		 */
		File& operator=(const File& src);
		/**
		 *  Destructor.
		 */
		~File();

		/**
		 *  Determines if file exists.
		 *  @param p pool.
		 *  @return true if file exists.
		 */
		bool exists(log4cxx::helpers::Pool& p) const;
		/**
		 *  Determines length of file.  May not be accurate if file is current open.
		 *  @param p pool.
		 *  @return length of file.
		 */
		size_t length(log4cxx::helpers::Pool& p) const;
		/**
		 *  Determines last modification date.
		 *  @param p pool.
		 *  @return length of file.
		 */
		log4cxx_time_t lastModified(log4cxx::helpers::Pool& p) const;
		/**
		 *  Get final portion of file path.
		 *  @return file name.
		 */
		LogString getName() const;
		/**
		 *  Get file path.
		 *  @return file path.
		 */
		LogString getPath() const;
		/**
		 *  Set file path
		 */
		File& setPath(const LogString&);

		/**
		 *  Open file.  See apr_file_open for details.
		 *  @param file APR file handle.
		 *  @param flags flags.
		 *  @param perm permissions.
		 *  @param p pool.
		 *  @return APR_SUCCESS if successful.
		 */
		log4cxx_status_t open(apr_file_t** file, int flags,
			int perm, log4cxx::helpers::Pool& p) const;

		/**
		 *   List files if current file is a directory.
		 *   @param p pool.
		 *   @return list of files in this directory, operation of non-directory returns empty list.
		 */
		std::vector<LogString> list(log4cxx::helpers::Pool& p) const;

		/**
		 *   Delete file.
		 *   @param p pool.
		 *   @return true if file successfully deleted.
		 */
		bool deleteFile(log4cxx::helpers::Pool& p) const;
		/**
		 *   Rename file.
		 *   @param dest new path for file.
		 *   @param p pool.
		 *   @return true if file successfully renamed.
		 */
		bool renameTo(const File& dest, log4cxx::helpers::Pool& p) const;

		/**
		 *   Get path of parent directory.
		 *   @param p pool.
		 *   @return path of parent directory.
		 */
		LogString getParent(log4cxx::helpers::Pool& p) const;
		/**
		 *  Make directories recursively.
		 *  @param p pool.
		 *  @return true if all requested directories existed or have been created.
		 */
		bool mkdirs(log4cxx::helpers::Pool& p) const;

	private:
		LogString path;
		static char* convertBackSlashes(char*);
		char* getPath(log4cxx::helpers::Pool& p) const;
};
} // namespace log4cxx


#if defined(_MSC_VER)
	#pragma warning (pop)
#endif

#define LOG4CXX_FILE(name) log4cxx::File(name)

#endif // _LOG4CXX_FILE_H
