//------------------------------------------------------------------------------
// <copyright file="LqrSMACFindFile.cpp" company="LiquidRobotics">
//
// Copyright (c) 2014 Liquid Robotics, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// This software is associated with a release.  Liquid Robotics makes no
// representation that the design, interfaces or component distribution will
// remain unchanged in future releases.
//
// </copyright>
//
// <summary>
// Implementsfind file methods
// </summary>
//
// <owner>Mike Cookson</owner>
//------------------------------------------------------------------------------

#include "LqrSMACFindFile.h"
#include <cstdio>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>

using namespace std;
using namespace boost;
using namespace boost::filesystem;

namespace LiquidRobotics {
namespace SMACFramework {

SHARED_LIB_PUBLIC string FindFileWithExecutable(const string& fileName, const string& executableName, bool throwOnError)
{
	path fileNameStartPath(fileName);

	if (is_regular_file(fileNameStartPath))
		return fileName;

	path fileNameOnly = fileNameStartPath.filename();

	if (fileNameOnly != fileNameStartPath)
		return fileName;

	if (is_regular_file(fileNameOnly))
		return fileNameOnly.string();

	stringstream cmd;
	cmd << "which '" << executableName << "'";

	string cmdStr = cmd.str();
	FILE* fp = popen(cmdStr.c_str(), "r");

	if (!fp)
	{
		if (throwOnError)
		{
			stringstream msg;
			msg << "Cannot execute command '" << cmdStr << "' to determine the location of '" << executableName << "'";
			throw runtime_error(msg.str());
		}
		else
			return fileName;
	}

	stringstream output;
	char c;

	while(c = fgetc(fp), !ferror(fp) && !feof(fp))
		output << c;

	pclose(fp);

	string outputStr = output.str();

	trim(outputStr);

	if (!outputStr.length())
	{
		if (throwOnError)
		{
			stringstream msg;
			msg << "No response from command '" << cmdStr << "'";
			throw runtime_error(msg.str());
		}
		else
			return fileName;
	}

	path outPath(outputStr);

	if (!exists(outPath))
	{
		if (throwOnError)
		{
			stringstream msg;
			msg << "Response from command '" << cmdStr << "' (" << outputStr << ") does not exist";
			throw runtime_error(msg.str());
		}
		else
			return fileName;
	}

	path outPath2 = outPath.parent_path();
	outPath2 /= fileName;

	string outPath2Str = outPath2.string();

	if (!is_regular_file(outPath2))
	{
		if (throwOnError)
		{
			stringstream msg;
			msg << "Resulting file named '" << outPath2Str << "' does not exist";
			throw runtime_error(msg.str());
		}
		else
			return fileName;
	}

	return outPath2Str;
}

}
}
