/*
 * synergy -- mouse and keyboard sharing utility
 * Copyright (C) 2013 Synergy Si Ltd.
 * 
 * This package is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * found in the file LICENSE that should have accompanied this file.
 * 
 * This package 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 General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "synergy/DragInformation.h"
#include "base/Log.h"

#include <fstream>
#include <sstream>
#include <stdexcept>

using namespace std;

DragInformation::DragInformation() :
	m_filename(),
	m_filesize(0)
{
}

void
DragInformation::parseDragInfo(DragFileList& dragFileList, UInt32 fileNum, String data)
{
	size_t startPos = 0;
	size_t findResult1 = 0;
	size_t findResult2 = 0;
	dragFileList.clear();
	String slash("\\");
	if (data.find("/", startPos) != string::npos) {
		slash = "/";
	}
	
	UInt32 index = 0;
	while (index < fileNum) {
		findResult1 = data.find(',', startPos);
		findResult2 = data.find_last_of(slash, findResult1);

		if (findResult1 == startPos) {
			//TODO: file number does not match, something goes wrong
			break;
		}
		
		// set filename
		if (findResult1 - findResult2 > 1) {
			String filename = data.substr(findResult2 + 1,
				findResult1 - findResult2 - 1);
			DragInformation di;
			di.setFilename(filename);
			dragFileList.push_back(di);
		}
		startPos = findResult1 + 1;
		
		//set filesize
		findResult2 = data.find(',', startPos);
		if (findResult2 - findResult1 > 1) {
			String filesize = data.substr(findResult1 + 1,
										   findResult2 - findResult1 - 1);
			size_t size = stringToNum(filesize);
			dragFileList.at(index).setFilesize(size);
		}
		startPos = findResult1 + 1;
		
		++index;
	}

	LOG((CLOG_DEBUG "drag info received, total drag file number: %i",
		dragFileList.size()));

	for (size_t i = 0; i < dragFileList.size(); ++i) {
		LOG((CLOG_DEBUG "dragging file %i name: %s",
			i + 1,
			dragFileList.at(i).getFilename().c_str()));
	}
}

String
DragInformation::getDragFileExtension(String filename)
{
	size_t findResult = string::npos;
	findResult = filename.find_last_of(".", filename.size());
	if (findResult != string::npos) {
		return filename.substr(findResult + 1, filename.size() - findResult - 1);
	}
	else {
		return "";
	}
}

int
DragInformation::setupDragInfo(DragFileList& fileList, String& output)
{
	int size = static_cast<int>(fileList.size());
	for (int i = 0; i < size; ++i) {
		output.append(fileList.at(i).getFilename());
		output.append(",");
		String filesize = getFileSize(fileList.at(i).getFilename());
		output.append(filesize);
		output.append(",");
	}
	return size;
}

bool
DragInformation::isFileValid(String filename)
{
	bool result = false;
	std::fstream file(filename.c_str(), ios::in|ios::binary);

	if (file.is_open()) {
		result = true;
	}

	file. close();

	return result;
}

size_t
DragInformation::stringToNum(String& str)
{
	istringstream iss(str.c_str());
	size_t size;
	iss >> size;
	return size;
}

String
DragInformation::getFileSize(String& filename)
{
	std::fstream file(filename.c_str(), ios::in|ios::binary);

	if (!file.is_open()) {
	  throw std::runtime_error("failed to get file size");
	}

	// check file size
	file.seekg (0, std::ios::end);
	size_t size = (size_t)file.tellg();

	stringstream ss;
	ss << size;
	
	file. close();
	
	return ss.str();
}
