/*  $Id: TestXmlsq.cpp $
 *   Last updated:
 *   $Date: 2021-07-16 09:02:00 $
 *   $Version: 1.0.0 $
 */

/******************************* LICENSE ***********************************
* Copyright (C) 2021 David Ireland, DI Management Services Pty Limited.
* All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
* The code in this module is licensed under the terms of the MIT license.
* For a copy, see <http://opensource.org/licenses/MIT>
****************************************************************************
*/

#include <iostream>
#include <string>
#include <clocale>
#include "xmlsq.hpp"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>	// For ``SetConsoleOutputCP(CP_UTF8);``
#endif

using std::cout;
using std::endl;

int main()
{
	std::string qout;
	int n;

	// Set up console and locale for UTF-8 characters
	std::setlocale(LC_ALL, "en_US.utf8");
#ifdef _WIN32
	// Save current code page
	UINT cpid = GetConsoleCP();
	// Set console display page to UTF-8
	SetConsoleOutputCP(CP_UTF8);
#endif

	cout << "__cplusplus=" << __cplusplus << endl;
	// General diagnostics
	cout << "xmlsq::Gen::Version=" << xmlsq::Gen::Version() << endl;
	cout << "xmlsq::Gen::CompileTime=" << xmlsq::Gen::CompileTime() << endl;
	cout << "xmlsq::Gen::ModuleName=" << xmlsq::Gen::ModuleName() << endl;
	cout << "xmlsq::Gen::Platform=" << xmlsq::Gen::Platform() << endl;


	// xmlsq queries...
	cout << "\nQUERIES..." << endl;

	qout = xmlsq::Query::FullQuery("bookstore.xml", "/");
	cout << "xmlsq::Query::FullQuery = \n" << qout  << endl;
	qout = xmlsq::Query::GetText("bookstore.xml", "(//title)[2]");
	cout << "xmlsq::Query::GetText = [" << qout << "]" << endl;
	qout = xmlsq::Query::GetText("bookstore.xml", "(//title)[3]", xmlsq::Query::Asciify | xmlsq::Query::Trim);
	cout << "xmlsq::Query::GetText = [" << qout << "]" << endl;
	qout = xmlsq::Query::FullQuery("bookstore.xml", "(//title)[3]", xmlsq::Query::Asciify | xmlsq::Query::Trim | xmlsq::Query::Raw);
	cout << "xmlsq::Query::FullQuery = [" << qout << "]" << endl;
	qout = xmlsq::Query::FullQuery("bookstore.xml", "(//book)[1]");
	cout << "xmlsq::Query::FullQuery = \n[" << qout << "]" << endl;
	qout = xmlsq::Query::FullQuery("bookstore.xml", "(//book)[1]", xmlsq::Query::Trim | xmlsq::Query::Raw);
	cout << "xmlsq::Query::FullQuery = \n[" << qout << "]" << endl;
	n = xmlsq::Query::Count("bookstore.xml", "//book");
	cout << "xmlsq::Query::Count=" << n << endl;

	cout << "Output encoded in UTF-8..." << endl;
	qout = xmlsq::Query::GetText("bookstore.xml", "(//title)[3]");
	cout << "xmlsq::Query::GetText = [" << qout << "]" << endl;

	// Pass XML data as a string parameter
	cout << "Pass XML as a string" << endl;
	qout = xmlsq::Query::FullQuery("<a><b>abc</b><b>xyz</b></a>", "/", xmlsq::Query::Raw);
	cout << qout << endl;
	qout = xmlsq::Query::GetText("<a><b>abc</b><b>xyz</b></a>", "//b");
	cout << "xmlsq::Query::GetText = [" << qout << "]" << endl;
	qout = xmlsq::Query::FullQuery("<a><b>abc</b><b>xyz</b></a>", "//b", xmlsq::Query::Raw);
	cout << "xmlsq::Query::FullQuery = [" << qout << "]" << endl;
	n = xmlsq::Query::Count("<a><b>abc</b><b>xyz</b></a>", "//b");
	cout << "xmlsq::Query::Count=" << n << endl;


	std::string xmlstr = "<a><b>abc</b><b foo='bar'>efg</b><b /></a>";
	qout = xmlsq::Query::GetText(xmlstr, "/");
	cout  << qout  << endl;
	qout = xmlsq::Query::GetText("<a><b>abc</b><b foo='bar'>efg</b><b /></a>", "//b");
	cout << "xmlsq::Query::GetText = [" << qout << "]" << endl;
	qout = xmlsq::Query::FullQuery(xmlstr, "//b", xmlsq::Query::Raw);
	cout << "xmlsq::Query::FullQuery = [" << qout << "]" << endl;
	n = xmlsq::Query::Count(xmlstr, "//b");
	cout << "xmlsq::Query::Count=" << n << endl;
	qout = xmlsq::Query::GetText(xmlstr, "//b[3]");
	cout << "xmlsq::Query::GetText = [" << qout << "]" << endl;
	n = xmlsq::Query::Count(xmlstr, "//b[3]");
	cout << "xmlsq::Query::Count=" << n << endl;


	// Errors and exceptions...
	cout << "\nERRORS & EXCEPTIONS..." << endl;
	try {
		qout = xmlsq::Query::GetText("missing.file", "(//title)[2]");
	}
	catch (std::exception& e) {
		cout << e.what() << endl;
	}
	try {
		qout = xmlsq::Query::GetText("badxml.xml", "(//title)[2]");
	}
	catch (std::exception& e) {
		cout << e.what() << endl;
	}
	
	try {
		qout = xmlsq::Query::GetText("bookstore.xml", "BAD_QUERY\\#ARRGH");
	}
	catch (std::exception& e) {
		cout << e.what() << endl;
	}
	try {
		qout = xmlsq::Query::Count("bookstore.xml", "BAD_QUERY\\#ARRGH");
	}
	catch (std::exception& e) {
		cout << e.what() << endl;
	}

#ifdef _WIN32
	// Uncomment the next line to restore original console code page
	//SetConsoleOutputCP(cpid);
#endif

	cout << "\nALL DONE." << endl;

	return 0;
}