/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <xalanc/XPathCAPI/XPathCAPI.h>



#include <assert.h>
#include <stdio.h>
#include <stdlib.h>



int
CreateXPath(
            XalanXPathEvaluatorHandle   theXalanHandle,
            const char*                 theXPathExpression,
            XalanXPathHandle*           theXPathHandle)
{
    int     theResult = 0;

    assert(theXalanHandle);
    assert(theXPathHandle);

    theResult = XalanCreateXPath(theXalanHandle, theXPathExpression, 0, theXPathHandle);

    if (theResult != XALAN_XPATH_API_SUCCESS)
    {
        fprintf(stderr, "Error creating XPath.  Error code was %d.\n", theResult);
    }

    return theResult;
}



int
DestroyXPath(
            XalanXPathEvaluatorHandle   theXalanHandle,
            XalanXPathHandle            theXPathHandle)
{
    int     theResult = 0;

    theResult = XalanDestroyXPath(theXalanHandle, theXPathHandle);

    if (theResult != XALAN_XPATH_API_SUCCESS)
    {
        fprintf(stderr, "Error destroying XPath.  Error code was %d.\n", theResult);
    }

    return theResult;
}



char*
ReadFile(const char*    theXMLFileName)
{
    char*   theBuffer = NULL;
    FILE*   theFile = fopen(theXMLFileName, "rb");

    if (theFile == 0)
    {
        fprintf(stderr, "Unable to open input file %s\n", theXMLFileName);
    }
    else
    {
        fseek(theFile, 0, SEEK_END);

        {
            const long  theSize = ftell(theFile);

            if (theSize == -1)
            {
                fprintf(stderr, "Unable to determine the size of the input file\n");
            }
            else
            {
                fseek(theFile, SEEK_SET, 0);

                theBuffer = (char*)malloc(theSize + 1);

                if (theBuffer == 0)
                {
                    fprintf(stderr, "Unable to allocate enough memory.  The input file size is %d\n", theSize);
                }
                else
                {
                    fread(theBuffer, 1, theSize, theFile);

                    theBuffer[theSize] = '\0';
                }
            }
        }

        fclose(theFile);
    }

    return theBuffer;
}



int
EvaluateXPath(
            XalanXPathEvaluatorHandle   theXalanHandle,
            const char*                 theXMLFileName,
            const char*                 theXPathExpression,
            int*                        theBoolean)
{
    XalanXPathHandle    theXPathHandle;

    int                 theResult = CreateXPath(theXalanHandle, theXPathExpression, &theXPathHandle);

    if (theResult == XALAN_XPATH_API_SUCCESS)
    {
        char*   theBuffer = ReadFile(theXMLFileName);

        if (theBuffer != NULL)
        {
            theResult = XalanEvaluateXPathAsBoolean(theXalanHandle, theXPathHandle, theBuffer, theBoolean);

            if (theResult != XALAN_XPATH_API_SUCCESS)
            {
                fprintf(stderr, "Unable to evaluate XPath expression.  Error code was %d.\n", theResult);
            }

            free(theBuffer);
        }

        DestroyXPath(theXalanHandle, theXPathHandle);
    }

    return theResult;
}



int
main(
            int     argc,
            char*   argv[])
{
    int     theResult = 0;

    if (argc != 3)
    {
        fprintf(stderr, "Usage: SimpleXPathAPI XMLFilePath XPathExpression\n");

        theResult = -1;
    }
    else
    {
        theResult = XalanXPathAPIInitialize();

        if (theResult != XALAN_XPATH_API_SUCCESS)
        {
            fprintf(stderr, "Unable to initialize the API.  Error code was %d.\n", theResult);
        }
        else
        {
            XalanXPathEvaluatorHandle   theXalanHandle;

            theResult = XalanCreateXPathEvaluator(&theXalanHandle);

            if (theResult != XALAN_XPATH_API_SUCCESS)
            {
                fprintf(stderr, "Error creating evaluator.  Error code was %d.\n", theResult);
            }
            else
            {
                int theBoolean = 0;

                theResult = EvaluateXPath(theXalanHandle, argv[1], argv[2], &theBoolean);

                if (theResult == XALAN_XPATH_API_SUCCESS)
                {
                    fprintf(stdout, "The result of the expression was '%s'.\n", theBoolean == 0 ? "false" : "true");
                }

                theResult = XalanDestroyXPathEvaluator(theXalanHandle);

                if (theResult != XALAN_XPATH_API_SUCCESS)
                {
                    fprintf(stderr, "Error destroying evaluator.  Error code was %d.\n", theResult);
                }
            }

            theResult = XalanXPathAPITerminate();

            if (theResult != XALAN_XPATH_API_SUCCESS)
            {
                fprintf(stderr, "Error terminating the API.  Error code was %d.\n", theResult);
            }
        }
    }

    return theResult;
}
