/*
* Copyright 2006 Sony Computer Entertainment Inc.
*
* Licensed under the MIT Open Source License, for details please see license.txt or the website
* http://www.opensource.org/licenses/mit-license.php
*
*/ 

#include <algorithm>
#include <dae.h>
#include <dae/daeURI.h>
#include <ctype.h>
#include <dae/daeDocument.h>
#include <dae/daeErrorHandler.h>
#include <dae/daeUtils.h>
#include <pcrecpp.h>

using namespace std;
using namespace cdom;

void daeURI::initialize() {
	reset();
	container = NULL;
}

daeURI::~daeURI() { }

daeURI::daeURI(DAE& dae) : dae(&dae) {
	initialize();
}

daeURI::daeURI(DAE& dae, const string& uriStr, daeBool nofrag) : dae(&dae) {
	initialize();

	if (nofrag) {
		size_t pos = uriStr.find_last_of('#');
		if (pos != string::npos) {
			set(uriStr.substr(0, pos));
			return;
		}
	}

	set(uriStr);
}

daeURI::daeURI(const daeURI& baseURI, const string& uriStr) : dae(baseURI.getDAE())
{
	initialize();
	set(uriStr, &baseURI);
}

daeURI::daeURI(const daeURI& copyFrom_) : dae(copyFrom_.getDAE()), container(NULL)
{
	initialize();
	copyFrom(copyFrom_);
}

daeURI::daeURI(daeElement& container_, const std::string& uriStr)
	: dae(container_.getDAE())
{
	initialize();
	container = &container_;
	set(uriStr);
}

daeURI::daeURI(DAE& dae, daeElement& container_, const string& uriStr)
	: dae(&dae)
{
	initialize();
	container = &container_;
	set(uriStr);
}

void
daeURI::copyFrom(const daeURI& copyFrom)
{
	if (!container)
		container = copyFrom.container;
	set(copyFrom.originalStr());
}

daeURI& daeURI::operator=(const daeURI& other) {
	copyFrom(other);
	return *this;
}

daeURI& daeURI::operator=(const string& uriStr) {
	set(uriStr);
	return *this;
}

void daeURI::reset() {
	// Clear everything except the container, which doesn't change for the lifetime of the daeURI
	uriString	         = "";
	originalURIString	 = "";
	_scheme            = "";
	_authority	       = "";
	_path              = "";
	_query             = "";
	_fragment          = "";
}

DAE* daeURI::getDAE() const {
	return dae;
}


const string& daeURI::str() const {
	return uriString;
}

const string& daeURI::originalStr() const {
	return originalURIString;
}

daeString daeURI::getURI() const {
	return str().c_str();
}

daeString daeURI::getOriginalURI() const {
	return originalStr().c_str();
}


namespace {
	void parsePath(const string& path,
	               /* out */ string& dir,
	               /* out */ string& baseName,
	               /* out */ string& extension) {
		// !!!steveT Currently, if we have a file name that begins with a '.', as in
		// ".emacs", that will be treated as having no base name with an extension
		// of ".emacs". We might want to change this behavior, so that the base name
		// is considered ".emacs" and the extension is empty. I think this is more
		// in line with what path parsers in other libraries/languages do, and it
		// more accurately reflects the intended structure of the file name.

        // The following implementation cannot handle paths like this:
        // /tmp/se.3/file
        //static pcrecpp::RE re("(.*/)?([^.]*)?(\\..*)?");
		//dir = baseName = extension = "";
		//re.FullMatch(path, &dir, &baseName, &extension);

        static pcrecpp::RE findDir("(.*/)?(.*)?");
        static pcrecpp::RE findExt("([^.]*)?(\\..*)?");
        string tmpFile;
        dir = baseName = extension = tmpFile = "";
        findDir.PartialMatch(path, &dir, &tmpFile);
        findExt.PartialMatch(tmpFile, &baseName, &extension);
	}
}

void daeURI::set(const string& uriStr_, const daeURI* baseURI) {
	// We make a copy of the uriStr so that set(originalURIString, ...) works properly.
	string uriStr = uriStr_;
	reset();
	originalURIString = uriStr;

	if (!parseUriRef(uriStr, _scheme, _authority, _path, _query, _fragment)) {
		reset();
		return;
	}

	validate(baseURI);
}

void daeURI::set(const string& scheme_,
                 const string& authority_,
                 const string& path_,
                 const string& query_,
                 const string& fragment_,
                 const daeURI* baseURI)
{
	set(assembleUri(scheme_, authority_, path_, query_, fragment_), baseURI);
}

void daeURI::setURI(daeString _URIString, const daeURI* baseURI) {
	string uriStr = _URIString ? _URIString : "";
	set(uriStr, baseURI);
}


const string& daeURI::scheme() const { return _scheme; }
const string& daeURI::authority() const { return _authority; }
const string& daeURI::path() const { return _path; }
const string& daeURI::query() const { return _query; }
const string& daeURI::fragment() const { return _fragment; }
const string& daeURI::id() const { return fragment(); }


namespace {
	string addSlashToEnd(const string& s) {
		return (!s.empty() && s[s.length()-1] != '/')  ?  s + '/' : s;
	}
}

void daeURI::pathComponents(string& dir, string& baseName, string& ext) const {
	parsePath(_path, dir, baseName, ext);
}

string daeURI::pathDir() const {
	string dir, base, ext;
	parsePath(_path, dir, base, ext);
	return dir;
}

string daeURI::pathFileBase() const {
	string dir, base, ext;
	parsePath(_path, dir, base, ext);
	return base;
}

string daeURI::pathExt() const {
	string dir, base, ext;
	parsePath(_path, dir, base, ext);
	return ext;
}

string daeURI::pathFile() const {
	string dir, base, ext;
	parsePath(_path, dir, base, ext);
	return base + ext;
}

void daeURI::path(const string& dir, const string& baseName, const string& ext) {
	path(addSlashToEnd(dir) + baseName + ext);
}

void daeURI::pathDir(const string& dir) {
	string tmp, base, ext;
	parsePath(_path, tmp, base, ext);
	path(addSlashToEnd(dir), base, ext);
}

void daeURI::pathFileBase(const string& baseName) {
	string dir, tmp, ext;
	parsePath(_path, dir, tmp, ext);
	path(dir, baseName, ext);
}

void daeURI::pathExt(const string& ext) {
	string dir, base, tmp;
	parsePath(_path, dir, base, tmp);
	path(dir, base, ext);
}

void daeURI::pathFile(const string& file) {
	string dir, base, ext;
	parsePath(_path, dir, base, ext);
	path(dir, file, "");
}


daeString daeURI::getScheme() const { return _scheme.c_str(); }
daeString daeURI::getProtocol() const {	return getScheme(); }
daeString daeURI::getAuthority() const { return _authority.c_str(); }
daeString daeURI::getPath() const { return _path.c_str(); }
daeString daeURI::getQuery() const { return _query.c_str(); }
daeString daeURI::getFragment() const { return _fragment.c_str(); }
daeString daeURI::getID() const { return getFragment(); }
daeBool daeURI::getPath(daeChar *dest, daeInt size) const {
	if (int(_path.length()) < size) {
		strcpy(dest, _path.c_str());
		return true;
	}
	return false;
}


void daeURI::scheme(const string& scheme_) { set(scheme_, _authority, _path, _query, _fragment); };
void daeURI::authority(const string& authority_) { set(_scheme, authority_, _path, _query, _fragment); }
void daeURI::path(const string& path_) { set(_scheme, _authority, path_, _query, _fragment); }
void daeURI::query(const string& query_) { set(_scheme, _authority, _path, query_, _fragment); }
void daeURI::fragment(const string& fragment_) { set(_scheme, _authority, _path, _query, fragment_); }
void daeURI::id(const string& id) { fragment(id); }

void
daeURI::print()
{
	fprintf(stderr,"URI(%s)\n",uriString.c_str());
	fprintf(stderr,"scheme = %s\n",_scheme.c_str());
	fprintf(stderr,"authority = %s\n",_authority.c_str());
	fprintf(stderr,"path = %s\n",_path.c_str());
	fprintf(stderr,"query = %s\n",_query.c_str());
	fprintf(stderr,"fragment = %s\n",_fragment.c_str());
	fprintf(stderr,"URI without base = %s\n",originalURIString.c_str());
	fflush(stderr);
}

namespace {
	void normalize(string& path) {
		daeURI::normalizeURIPath(const_cast<char*>(path.c_str()));
		path = path.substr(0, strlen(path.c_str()));
	}
}

void
daeURI::validate(const daeURI* baseURI)
{
	// If no base URI was supplied, use the container's document URI. If there's
	// no container or the container doesn't have a doc URI, use the application
	// base URI.
	if (!baseURI) {
		if (container)
        {
            if (container->getDocument())
            {
                if (container->getDocument()->isZAERootDocument())
                    baseURI = &container->getDocument()->getExtractedFileURI();
                else
                    baseURI = container->getDocumentURI();
            }
        }
        if (!baseURI)
            baseURI = &dae->getBaseURI();
		if (this == baseURI)
			return;
	}

	// This is rewritten according to the updated rfc 3986
	if (!_scheme.empty()) // if defined(R.scheme) then
	{
		// Everything stays the same except path which we normalize
		// T.scheme    = R.scheme;
		// T.authority = R.authority;
		// T.path      = remove_dot_segments(R.path);
		// T.query     = R.query;
		normalize(_path);
	}
	else
	{
		if (!_authority.empty()) // if defined(R.authority) then
		{
			// Authority and query stay the same, path is normalized
			// T.authority = R.authority;
			// T.path      = remove_dot_segments(R.path);
			// T.query     = R.query;
			normalize(_path);
		}
		else
		{
			if (_path.empty())  // if (R.path == "") then
			{
				// T.path = Base.path;
				_path = baseURI->_path;

				//if defined(R.query) then
				//   T.query = R.query;
				//else
				//   T.query = Base.query;
				//endif;
				if (_query.empty())
					_query = baseURI->_query;
			}
			else
			{
				if (_path[0] == '/')  // if (R.path starts-with "/") then
				{
					// T.path = remove_dot_segments(R.path);
					normalize(_path);
				}
				else
				{
					// T.path = merge(Base.path, R.path);
					if (!baseURI->_authority.empty() && baseURI->_path.empty()) // authority defined, path empty
						_path.insert(0, "/");
					else {
						string dir, baseName, ext;
						parsePath(baseURI->_path, dir, baseName, ext);
						_path = dir + _path;
					}
					// T.path = remove_dot_segments(T.path);
					normalize(_path);
				}
				// T.query = R.query;
			}
			// T.authority = Base.authority;
			_authority = baseURI->_authority;
		}
		// T.scheme = Base.scheme;
		_scheme = baseURI->_scheme;
	}
	// T.fragment = R.fragment;

	// Reassemble all this into a string version of the URI
	uriString = assembleUri(_scheme, _authority, _path, _query, _fragment);
}

daeElementRef daeURI::getElement() const {
	return internalResolveElement();
}

daeElement* daeURI::internalResolveElement() const {
	if (uriString.empty())
		return NULL;
	
	return dae->getURIResolvers().resolveElement(*this);
}

void daeURI::resolveElement() { }

void daeURI::setContainer(daeElement* cont) {
	container = cont;
	// Since we have a new container element, the base URI may have changed. Re-resolve.
	set(originalURIString);
}

daeBool daeURI::isExternalReference() const {
	if (uriString.empty())
		return false;
	
	if (container && container->getDocumentURI()) {
		daeURI* docURI = container->getDocumentURI();
		if (_path != docURI->_path ||
		    _scheme != docURI->_scheme ||
		    _authority != docURI->_authority) {
			return true;
		}
	}

	return false;
}


daeDocument* daeURI::getReferencedDocument() const {
	string doc = assembleUri(_scheme, _authority, _path, "", "");
	return dae->getDatabase()->getDocument(doc.c_str(), true);
}

daeURI::ResolveState daeURI::getState() const {
	return uriString.empty() ? uri_empty : uri_loaded;
}

void daeURI::setState(ResolveState newState) { }


// This code is loosely based on the RFC 2396 normalization code from
// libXML. Specifically it does the RFC steps 6.c->6.g from section 5.2
// The path is modified in place, there is no error return.
void daeURI::normalizeURIPath(char* path)
{
	char *cur, // location we are currently processing
	     *out; // Everything from this back we are done with

	// Return if the path pointer is null

	if (path == NULL) return;

	// Skip any initial / characters to get us to the start of the first segment

	for(cur=path; *cur == '/'; cur++);

	// Return if we hit the end of the string

	if (*cur == 0) return;

	// Keep everything we've seen so far.
    
	out = cur;

	// Analyze each segment in sequence for cases (c) and (d).

	while (*cur != 0) 
	{
		// (c) All occurrences of "./", where "." is a complete path segment, are removed from the buffer string.
		
		if ((*cur == '.') && (*(cur+1) == '/')) 
		{
			cur += 2;
			// If there were multiple slashes, skip them too
			while (*cur == '/') cur++;
			continue;
		}

		// (d) If the buffer string ends with "." as a complete path segment, that "." is removed.

		if ((*cur == '.') && (*(cur+1) == 0))
			break;

		// If we passed the above tests copy the segment to the output side

		while (*cur != '/' && *cur != 0)
		{
			*(out++) = *(cur++);
		}

		if(*cur != 0)
		{
			// Skip any occurrances of // at the end of the segment

			while ((*cur == '/') && (*(cur+1) == '/')) cur++;

			// Bring the last character in the segment (/ or a null terminator) into the output
        
			*(out++) = *(cur++);
		}
	}

	*out = 0;

    // Restart at the beginning of the first segment for the next part

	for(cur=path; *cur == '/'; cur++);
	if (*cur == 0) return;

	// Analyze each segment in sequence for cases (e) and (f).
	//
	// e) All occurrences of "<segment>/../", where <segment> is a
	//    complete path segment not equal to "..", are removed from the
	//    buffer string.  Removal of these path segments is performed
	//    iteratively, removing the leftmost matching pattern on each
	//    iteration, until no matching pattern remains.
	//
	// f) If the buffer string ends with "<segment>/..", where <segment>
	//    is a complete path segment not equal to "..", that
	//    "<segment>/.." is removed.
	//
	// To satisfy the "iterative" clause in (e), we need to collapse the
	// string every time we find something that needs to be removed.  Thus,
	// we don't need to keep two pointers into the string: we only need a
	// "current position" pointer.
	//
	while (true)
	{
		char *segp, *tmp;

		// At the beginning of each iteration of this loop, "cur" points to
		// the first character of the segment we want to examine.

		// Find the end of the current segment.  
        
		for(segp = cur;(*segp != '/') && (*segp != 0); ++segp);

		// If this is the last segment, we're done (we need at least two
		// segments to meet the criteria for the (e) and (f) cases).

		if (*segp == 0)
			break;

		// If the first segment is "..", or if the next segment _isn't_ "..",
		// keep this segment and try the next one.

		++segp;
		if (((*cur == '.') && (cur[1] == '.') && (segp == cur+3))
            || ((*segp != '.') || (segp[1] != '.')
            || ((segp[2] != '/') && (segp[2] != 0)))) 
		{
			cur = segp;
			continue;
		}

		// If we get here, remove this segment and the next one and back up
		// to the previous segment (if there is one), to implement the
		// "iteratively" clause.  It's pretty much impossible to back up
		// while maintaining two pointers into the buffer, so just compact
		// the whole buffer now.

		// If this is the end of the buffer, we're done.

		if (segp[2] == 0) 
		{
			*cur = 0;
			break;
		}

		// Strings overlap during this copy, but not in a bad way, just avoid using strcpy
		
		tmp = cur;
		segp += 3;
		while ((*(tmp++) = *(segp++)) != 0);

		// If there are no previous segments, then keep going from here.
        
		segp = cur;
		while ((segp > path) && (*(--segp) == '/'));
        
		if (segp == path)
			continue;

		// "segp" is pointing to the end of a previous segment; find it's
		// start.  We need to back up to the previous segment and start
		// over with that to handle things like "foo/bar/../..".  If we
		// don't do this, then on the first pass we'll remove the "bar/..",
		// but be pointing at the second ".." so we won't realize we can also
		// remove the "foo/..".

		for(cur = segp;(cur > path) && (*(cur-1) != '/'); cur--);
	}

	*out = 0;

	// g) If the resulting buffer string still begins with one or more
	//    complete path segments of "..", then the reference is
	//    considered to be in error. Implementations may handle this
	//    error by retaining these components in the resolved path (i.e.,
	//    treating them as part of the final URI), by removing them from
	//    the resolved path (i.e., discarding relative levels above the
	//    root), or by avoiding traversal of the reference.
	//
	// We discard them from the final path.

	if (*path == '/') 
	{
		for(cur=path; (*cur == '/') && (cur[1] == '.') && (cur[2] == '.') && ((cur[3] == '/') || (cur[3] == 0)); cur += 3);

		if (cur != path) 
		{
			for(out=path; *cur != 0; *(out++) = *(cur++));

			*out = 0;
		}
	}
	return;
}

// This function will take a resolved URI and create a version of it that is relative to
// another existing URI.  The new URI is stored in the "originalURI"
int daeURI::makeRelativeTo(const daeURI* relativeToURI)
{
	// Can only do this function if both URIs have the same scheme and authority
	if (_scheme != relativeToURI->_scheme  ||  _authority != relativeToURI->_authority)
		return DAE_ERR_INVALID_CALL;

	// advance till we find a segment that doesn't match
	const char *this_path        = getPath();
	const char *relativeTo_path  = relativeToURI->getPath();
	const char *this_slash       = this_path;
	const char *relativeTo_slash = relativeTo_path;

	while((*this_path == *relativeTo_path) && *this_path)
	{
		if(*this_path == '/')
		{
			this_slash = this_path;
			relativeTo_slash = relativeTo_path;
		}
		this_path++;
		relativeTo_path++;
	}

	// Decide how many ../ segments are needed (Filepath should always end in a /)
	int segment_count = 0;
	relativeTo_slash++;
	while(*relativeTo_slash != 0)
	{
		if(*relativeTo_slash == '/')
			segment_count ++;
		relativeTo_slash++;
	}
	this_slash++;

	string newPath;
	for (int i = 0; i < segment_count; i++)
		newPath += "../";
	newPath += this_slash;
	
	set("", "", newPath, _query, _fragment, relativeToURI);
	return(DAE_OK);
}


daeBool daeURIResolver::_loadExternalDocuments = true;

daeURIResolver::daeURIResolver(DAE& dae) : dae(&dae) { }

daeURIResolver::~daeURIResolver() { }

void daeURIResolver::setAutoLoadExternalDocuments( daeBool load ) 
{ 
	_loadExternalDocuments = load; 
}

daeBool daeURIResolver::getAutoLoadExternalDocuments() 
{ 
	return _loadExternalDocuments; 
}


daeURIResolverList::daeURIResolverList() { }

daeURIResolverList::~daeURIResolverList() {
	for (size_t i = 0; i < resolvers.getCount(); i++)
		delete resolvers[i];
}

daeTArray<daeURIResolver*>& daeURIResolverList::list() {
	return resolvers;
}

daeElement* daeURIResolverList::resolveElement(const daeURI& uri) {
	for (size_t i = 0; i < resolvers.getCount(); i++)
		if (daeElement* elt = resolvers[i]->resolveElement(uri))
			return elt;
	return NULL;
}


// Returns true if parsing succeeded, false otherwise. Parsing can fail if the uri
// reference isn't properly formed.
bool cdom::parseUriRef(const string& uriRef,
                       string& scheme,
                       string& authority,
                       string& path,
                       string& query,
                       string& fragment) {
	// This regular expression for parsing URI references comes from the URI spec:
	//   http://tools.ietf.org/html/rfc3986#appendix-B
	static pcrecpp::RE re("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
	string s1, s3, s6, s8;
	if (re.FullMatch(uriRef, &s1, &scheme, &s3, &authority, &path, &s6, &query, &s8, &fragment))
		return true;

	return false;
}

namespace {
	string safeSubstr(const string& s, size_t offset, size_t length) {
		string result = s.substr(offset, min(length, s.length() - offset));
		result.resize(length, '\0');
		return result;
	}
}

string cdom::assembleUri(const string& scheme,
                         const string& authority,
                         const string& path,
                         const string& query,
                         const string& fragment,
                         bool forceLibxmlCompatible) {
	string p = safeSubstr(path, 0, 3);
	bool libxmlHack = forceLibxmlCompatible && scheme == "file";
	bool uncPath = false;
	string uri;

	if (!scheme.empty())
		uri += scheme + ":";

	if (!authority.empty() || libxmlHack || (p[0] == '/' && p[1] == '/'))
		uri += "//";
	if (!authority.empty()) {
		if (libxmlHack) {
			// We have a UNC path URI of the form file://otherMachine/file.dae.
			// Convert it to file://///otherMachine/file.dae, which is how libxml
			// does UNC paths.
			uri += "///" + authority;
			uncPath = true;
		}
		else {
			uri += authority;
		}
	}

	if (!uncPath && libxmlHack && getSystemType() == Windows) {
		// We have to be delicate in how we pass absolute path URIs to libxml on Windows.
		// If the path is an absolute path with no drive letter, add an extra slash to
		// appease libxml.
		if (p[0] == '/' && p[1] != '/' && p[2] != ':') {
			uri += "/";
		}
	}
	uri += path;
	
	if (!query.empty())
		uri += "?" + query;
	if (!fragment.empty())
		uri += "#" + fragment;

	return uri;
}

string cdom::fixUriForLibxml(const string& uriRef) {
	string scheme, authority, path, query, fragment;
	cdom::parseUriRef(uriRef, scheme, authority, path, query, fragment);
	return assembleUri(scheme, authority, path, query, fragment, true);
}


string cdom::nativePathToUri(const string& nativePath, systemType type) {
	string uri = nativePath;

	if (type == Windows) {
		// Convert "c:\" to "/c:/"
		if (uri.length() >= 2  &&  isalpha(uri[0])  &&  uri[1] == ':')
			uri.insert(0, "/");
		// Convert backslashes to forward slashes
		uri = replace(uri, "\\", "/");
	}

	// Convert spaces to %20
	uri = replace(uri, " ", "%20");

	return uri;
}

string cdom::filePathToUri(const string& filePath) {
	return nativePathToUri(filePath);
}

string cdom::uriToNativePath(const string& uriRef, systemType type) {
	string scheme, authority, path, query, fragment;
	parseUriRef(uriRef, scheme, authority, path, query, fragment);

	// Make sure we have a file scheme URI, or that it doesn't have a scheme
	if (!scheme.empty()  &&  scheme != "file")
		return "";

	string filePath;

	if (type == Windows) {
		if (!authority.empty())
			filePath += string("\\\\") + authority; // UNC path
	
		// Replace two leading slashes with one leading slash, so that
		// ///otherComputer/file.dae becomes //otherComputer/file.dae and
		// //folder/file.dae becomes /folder/file.dae
		if (path.length() >= 2  &&  path[0] == '/'  &&  path[1] == '/')
			path.erase(0, 1);

		// Convert "/C:/" to "C:/"
		if (path.length() >= 3  &&  path[0] == '/'  &&  path[2] == ':')
			path.erase(0, 1);

		// Convert forward slashes to back slashes
		path = replace(path, "/", "\\");
	}

	filePath += path;

	// Replace %20 with space
	filePath = replace(filePath, "%20", " ");
	
	return filePath;
}

string cdom::uriToFilePath(const string& uriRef) {
	return uriToNativePath(uriRef);
}
