#include <fstream>
#include <cstdio>

#include "myDbEnv.hpp"
#include "myXmlContainer.hpp"


using namespace DbXml;

void usage()
{
      std::cerr   << "This program retrieves DBXML documents and then retrieves the day and time the\n"
                  << "document was stored in the container. The date/time information was set as\n"
                  << "metadata information when the document was loaded. See the\n"
                  << "exampleLoadContainer.cpp example for how this metadata is set.\n\n" 

                  << "Before running this example, use loadExamplesData.[sh|cmd] to pre-load the\n"
                  << "appropriate container with documents and metadata. \n\n"

                  << "You are only required to pass this command the path location of the database\n"
                  << "environment that you specified when you pre-loaded the examples data:\n\n"

                  << "\t-h <dbenv directory>" << std::endl;
        exit( -1 );
}

void showTimeStamp( const XmlContainer &container, const std::string &XPath, XmlQueryContext &context )
{
    ////////////////////////////////////////////////////////////////////////
    //////  Performs a simple XPath query (with context) against the ///////
    //////  provided container. The timestamp metadata attribute     ///////
    //////  value is then displayed.                                 ///////
    ////////////////////////////////////////////////////////////////////////

    ///// some defensive code eliminated for clarity //

    //Used for metadata query
    const std::string mdURI = "http://dbxmlExamples/timestamp";
    const std::string mdPrefix = "time";
    const std::string mdName = "timeStamp";


    // Perform the query. Result type is by default Result Document

    
    try {
        std::cout << "Exercising query '" << XPath << "' " << std::endl;
        std::cout << "Return to continue: ";
        getc(stdin);

        XmlResults results( container.queryWithXPath(0, XPath, &context ) );
        XmlValue value;
        while( results.next(value) )
        {
            XmlDocument theDocument( value.asDocument(0) );

            //Get this document's name
            const std::string docName( theDocument.getName() );

            //Get the timestamp on the document (stored as metadata)
            // and print it to the console.
            XmlValue metaValue;
            theDocument.getMetaData( mdURI, mdName, metaValue );
            std::cout << "Document '" << docName << "' stored on " << metaValue.asString() << std::endl;
        }

        std::cout << results.size() << " objects returned for expression '" << XPath << "'\n" << std::endl;

    }
    //Catches XmlException
    catch(std::exception &e)
    {
        std::cerr << "Query " << XPath << " failed\n";
        std::cerr << e.what() << "\n";
        exit( -1 );
    }

}

int main(int argc, char **argv)
{

    std::string path2DbEnv;
    std::string theContainer = "namespaceExampleData.dbxml";
    for ( int i=1; i<argc; i++ )
    {
        if ( argv[i][0] == '-' )
        {
            switch(argv[i][1])
            {
              case 'h':
                path2DbEnv = argv[++i];
                break;
              default:
                usage();
            }
         }
     }

     if (! path2DbEnv.length() )
        usage();

    //open a container in the db environment
    myDbEnv theDBEnv( path2DbEnv ); 
    myXmlContainer openedContainer( theContainer, theDBEnv );

    //create a context and declare the namespaces
    XmlQueryContext context;
    context.setNamespace( "fruits", "http://groceryItem.dbxml/fruits");
    context.setNamespace( "vegetables", "http://groceryItem.dbxml/vegetables");
    context.setNamespace( "desserts", "http://groceryItem.dbxml/desserts");


    //Find all the vegetables
    showTimeStamp( openedContainer.getContainer(), "/vegetables:item", context);


    return 0;


}
