/*
 *  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.
 *
 */

/*
 *                        AT&T - PROPRIETARY
 *          THIS FILE CONTAINS PROPRIETARY INFORMATION OF
 *        AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
 *             ACCORDANCE WITH APPLICABLE AGREEMENTS.
 *
 *          Copyright (c) 2014 AT&T Knowledge Ventures
 *              Unpublished and Not for Publication
 *                     All Rights Reserved
 */
package org.apache.openaz.xacml.pdp.test;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.entity.ContentType;
import org.apache.openaz.xacml.api.AttributeValue;
import org.apache.openaz.xacml.api.DataType;
import org.apache.openaz.xacml.api.DataTypeException;
import org.apache.openaz.xacml.api.DataTypeFactory;
import org.apache.openaz.xacml.api.Decision;
import org.apache.openaz.xacml.api.Identifier;
import org.apache.openaz.xacml.api.Request;
import org.apache.openaz.xacml.api.RequestAttributes;
import org.apache.openaz.xacml.api.Response;
import org.apache.openaz.xacml.api.Result;
import org.apache.openaz.xacml.api.pdp.PDPEngine;
import org.apache.openaz.xacml.api.pdp.PDPEngineFactory;
import org.apache.openaz.xacml.api.pdp.PDPException;
import org.apache.openaz.xacml.api.pep.PEPException;
import org.apache.openaz.xacml.std.IdentifierImpl;
import org.apache.openaz.xacml.std.StdAttributeValue;
import org.apache.openaz.xacml.std.StdMutableAttribute;
import org.apache.openaz.xacml.std.StdMutableRequest;
import org.apache.openaz.xacml.std.StdMutableRequestAttributes;
import org.apache.openaz.xacml.std.dom.DOMRequest;
import org.apache.openaz.xacml.std.dom.DOMResponse;
import org.apache.openaz.xacml.std.dom.DOMStructureException;
import org.apache.openaz.xacml.std.json.JSONRequest;
import org.apache.openaz.xacml.std.json.JSONResponse;
import org.apache.openaz.xacml.std.json.JSONStructureException;
import org.apache.openaz.xacml.util.FactoryException;
import org.apache.openaz.xacml.util.XACMLProperties;

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;

/**
 * This is a base class for setting up a test environment. Using properties files, it contains the necessary
 * information for 1. defining and providing attributes 2. defining and instantiating the PDP engine 3.
 * creating PEP requests and calling the PDP engine
 */
public class TestBase extends SimpleFileVisitor<Path> {
    private static final Log logger = LogFactory.getLog(TestBase.class);

    public class HelpException extends Exception {
        private static final long serialVersionUID = 1L;

    }

    /**
     * This private class holds information for properties defined for attribute generation. The user can
     * configure the properties file such that attributes can be automatically generated and added into each
     * request.
     */
    class Generator {
        Path file;
        InputStream is;
        BufferedReader reader;
        List<StdMutableAttribute> attributes = new ArrayList<StdMutableAttribute>();

        public Generator(Path path) {
            this.file = path;
        }

        /**
         * read - reads in the next line of data
         *
         * @return String - a line from the csv containing attribute data
         */
        public String read() {
            String str = null;
            if (is == null) {
                try {
                    is = Files.newInputStream(file);
                } catch (IOException e) {
                    logger.error(e);
                    return null;
                }
            }
            if (reader == null) {
                reader = new BufferedReader(new InputStreamReader(this.is));
            }
            try {
                str = reader.readLine();
                if (str == null) {
                    //
                    // No more strings, close up
                    //
                    this.close();
                }
                if (logger.isDebugEnabled()) {
                    logger.debug(str);
                }
            } catch (IOException e) {
                logger.error(e);
            }
            return str;
        }

        public void close() {
            if (this.reader != null) {
                try {
                    this.reader.close();
                } catch (IOException idontcare) {
                } finally {
                    this.reader = null;
                    this.is = null;
                }
            }
        }

    }

    public static final String PROP_GENERATOR = "xacml.attribute.generator";

    public static final String OPTION_HELP = "help";
    public static final String OPTION_TESTDIR = "dir";
    public static final String OPTION_TESTREST = "rest";
    public static final String OPTION_TESTURL = "url";
    public static final String OPTION_TESTOUTPUT = "output";
    public static final String OPTION_LOOP = "loop";
    public static final String OPTION_TESTNUMBERS = "testNumbers";

    public static final String DEFAULT_RESTURL = "https://localhost:8443/pdp/";

    public static Options options = new Options();
    static {
        options.addOption(new Option(OPTION_HELP, false, "Prints help."));
        options.addOption(new Option(OPTION_TESTDIR, true,
                                     "Directory path where all the test properties and data are located."));
        options.addOption(new Option(OPTION_TESTREST, false, "Test against RESTful PDP."));
        options.addOption(new Option(OPTION_TESTURL, true, "URL to the RESTful PDP. Default is "
                                                           + DEFAULT_RESTURL));
        options.addOption(new Option(OPTION_TESTOUTPUT, true,
                                     "Specify a different location for dumping responses."));
        options
            .addOption(new Option(OPTION_LOOP, true,
                                  "Number of times to loop through the tests. Default is 1. A value of -1 runs indefinitely."));
        options
            .addOption(new Option(
                                  OPTION_TESTNUMBERS,
                                  true,
                                  "Comma-separated list of numbers found in the names of the test files to be run.  Numbers must exactly match the file name, e.g. '02'.  Used to limit testing to specific set of tests."));
    }

    protected String directory = null;
    protected Path output = null;
    protected boolean isREST;
    protected URL restURL = null;
    protected int loop = 1;
    protected PDPEngine engine = null;
    protected List<Generator> generators = new ArrayList<Generator>();
    protected static DataTypeFactory dataTypeFactory = null;

    private long permits = 0;
    private long denies = 0;
    private long notapplicables = 0;
    private long indeterminates = 0;

    private long expectedPermits = 0;
    private long expectedDenies = 0;
    private long expectedNotApplicables = 0;
    private long expectedIndeterminates = 0;

    private long generatedpermits = 0;
    private long generateddenies = 0;
    private long generatednotapplicables = 0;
    private long generatedindeterminates = 0;

    private long responseMatches = 0;
    private long responseNotMatches = 0;

    private String[] testNumbersArray = null;

    protected final Pattern pattern = Pattern
        .compile("Request[.]\\d+[.](Permit|Deny|NA|Indeterminate|Generate|Unknown)\\.(json|xml)");

    public static boolean isJSON(Path file) {
        return file.toString().endsWith(".json");
    }

    public static boolean isXML(Path file) {
        return file.toString().endsWith(".xml");
    }

    public TestBase(String[] args) throws ParseException, MalformedURLException, HelpException {
        //
        // Finish Initialization
        //
        this.restURL = new URL(DEFAULT_RESTURL);
        //
        // Parse arguments
        //
        this.parseCommands(args);
    }

    /**
     * Parse in the command line arguments that the following parameters:
     *
     * @param args - command line arguments
     * @throws org.apache.commons.cli.ParseException
     * @throws java.net.MalformedURLException
     * @throws org.apache.openaz.xacml.pdp.test.TestBase.HelpException
     */
    protected void parseCommands(String[] args) throws ParseException, MalformedURLException, HelpException {
        //
        // Parse the command line options
        //
        CommandLine cl = new DefaultParser().parse(options, args);
        //
        // Check for what we have
        //
        if (cl.hasOption(OPTION_HELP)) {
            new HelpFormatter().printHelp("Usage: -dir testdirectory OPTIONS", options);
            throw new HelpException();
        }
        if (cl.hasOption(OPTION_TESTDIR)) {
            this.directory = cl.getOptionValue(OPTION_TESTDIR);
        } else {
            throw new IllegalArgumentException("You must specify a test directory. -dir path/to/some/where");
        }
        if (cl.hasOption(OPTION_TESTREST)) {
            this.isREST = true;
        } else {
            this.isREST = false;
        }
        if (cl.hasOption(OPTION_TESTURL)) {
            this.restURL = new URL(cl.getOptionValue(OPTION_TESTURL));
        }
        if (cl.hasOption(OPTION_TESTOUTPUT)) {
            this.output = Paths.get(cl.getOptionValue(OPTION_TESTOUTPUT));
        } else {
            this.output = Paths.get(this.directory, "results");
        }
        if (cl.hasOption(OPTION_LOOP)) {
            this.loop = Integer.parseInt(cl.getOptionValue(OPTION_LOOP));
        }
        if (cl.hasOption(OPTION_TESTNUMBERS)) {
            String testNumberString = cl.getOptionValue(OPTION_TESTNUMBERS);
            testNumbersArray = testNumberString.split(",");
            //
            // reset strings to include dots so they exactly match pattern in file name
            //
            for (int i = 0; i < testNumbersArray.length; i++) {
                testNumbersArray[i] = "." + testNumbersArray[i] + ".";
            }
        }
    }

    /**
     * Using the command line options that were parsed, configures our test instance.
     *
     * @throws org.apache.openaz.xacml.util.FactoryException
     */
    protected void configure() throws FactoryException {
        //
        // Setup the xacml.properties file
        //
        if (this.directory == null) {
            throw new IllegalArgumentException("Must supply a path to a test directory.");
        }
        Path pathDir = Paths.get(this.directory, "xacml.properties");
        if (Files.notExists(pathDir)) {
            throw new IllegalArgumentException(pathDir.toString() + " does not exist.");
        }
        //
        // Set it as the System variable so the XACML factories know where the properties are
        // loaded from.
        //
        System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, pathDir.toString());
        //
        // Now we can create the data type factory
        //
        dataTypeFactory = DataTypeFactory.newInstance();
        //
        // Load in what generators we are to create
        //
        String generators = XACMLProperties.getProperty(PROP_GENERATOR);
        if (generators != null) {
            //
            // Parse the generators
            //
            for (String generator : Splitter.on(',').trimResults().omitEmptyStrings().split(generators)) {
                this.configureGenerator(generator);
            }
        }
        //
        // If we are embedded, create our engine
        //
        if (!this.isREST) {
            PDPEngineFactory factory = PDPEngineFactory.newInstance();
            this.engine = factory.newEngine();
        }
        //
        // Remove all the responses from the results directory
        //
        this.removeResults();
    }

    /**
     * Removes all the Response* files from the results directory.
     */
    public void removeResults() {
        try {
            //
            // Determine where the results are supposed to be written to
            //
            Path resultsPath;
            if (this.output != null) {
                resultsPath = this.output;
            } else {
                resultsPath = Paths.get(this.directory.toString(), "results");
            }
            //
            // Walk the files
            //
            Files.walkFileTree(resultsPath, new SimpleFileVisitor<Path>() {

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    if (file.getFileName().toString().startsWith("Response")) {
                        Files.delete(file);
                    }
                    return super.visitFile(file, attrs);
                }
            });
        } catch (IOException e) {
            logger.error("Failed to removeRequests from " + this.directory + " " + e);
        }
    }

    /**
     * Configure's a specific generator instance from the properties file.
     *
     * @param generator
     */
    protected void configureGenerator(String generator) {
        String prefix = PROP_GENERATOR + "." + generator;
        String file = XACMLProperties.getProperty(prefix + ".file");
        //
        // Create a generator object
        //
        Generator gen = new Generator(Paths.get(this.directory, file));
        this.generators.add(gen);
        //
        // Grab attributes
        //
        String attributes = XACMLProperties.getProperty(prefix + ".attributes");
        for (String attribute : Splitter.on(',').trimResults().omitEmptyStrings().split(attributes)) {
            String attributePrefix = prefix + ".attributes." + attribute;
            //
            // Create an attribute value. It is simply a placeholder for the field within
            // the CSV that contains the actual attribute value. It mainly holds the data type
            //
            Identifier datatype = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix
                                                                                 + ".datatype"));
            Integer field = Integer.parseInt(XACMLProperties.getProperty(attributePrefix + ".field"));
            StdAttributeValue<?> value = new StdAttributeValue<>(datatype, field);
            //
            // Get the rest of the attribute properties
            //
            Identifier category = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix
                                                                                 + ".category"));
            Identifier id = new IdentifierImpl(XACMLProperties.getProperty(attributePrefix + ".id"));
            String issuer = XACMLProperties.getProperty(attributePrefix + ".issuer");
            boolean include = Boolean.parseBoolean(XACMLProperties.getProperty(attributePrefix + ".include",
                                                                               "false"));
            //
            // Now we have a skeleton attribute
            //
            gen.attributes.add(new StdMutableAttribute(category, id, value, issuer, include));
        }
    }

    /**
     * This runs() the test instance. It first configure's itself and then walks the requests directory issue
     * each request to the PDP engine.
     *
     * @throws java.io.IOException
     * @throws org.apache.openaz.xacml.util.FactoryException
     */
    public void run() throws IOException, FactoryException {
        //
        // Configure ourselves
        //
        this.configure();
        //
        // Loop and run
        //
        int runs = 1;
        do {
            long lTimeStart = System.currentTimeMillis();
            logger.info("Run number: " + runs);
            //
            // Walk the request directory
            //
            Files.walkFileTree(Paths.get(this.directory.toString(), "requests"), this);
            long lTimeEnd = System.currentTimeMillis();
            logger.info("Run elapsed time: " + (lTimeEnd - lTimeStart) + "ms");
            //
            // Dump the stats
            //
            this.dumpStats();
            this.resetStats();
            //
            // Increment
            //
            runs++;
        } while ((this.loop == -1 ? true : runs <= this.loop));
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        //
        // Sanity check the file name
        //
        Matcher matcher = this.pattern.matcher(file.getFileName().toString());
        if (matcher.matches()) {
            //
            // if user has limited which files to use, check that here
            //
            if (testNumbersArray != null) {
                String fileNameString = file.getFileName().toString();
                boolean found = false;
                for (String numberString : testNumbersArray) {
                    if (fileNameString.contains(numberString)) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    //
                    // this test is not in the list to be run, so skip it
                    //
                    return super.visitFile(file, attrs);
                }
            }
            try {
                //
                // Pull what this request is supposed to be
                //
                String group = null;
                int count = matcher.groupCount();
                if (count >= 1) {
                    group = matcher.group(count - 1);
                }
                //
                // Send it
                //
                this.sendRequest(file, group);
            } catch (Exception e) {
                logger.error(e);
                e.printStackTrace();
            }
        }
        return super.visitFile(file, attrs);
    }

    /**
     * When a request file is encountered, this method is called send the request to the PDP engine. It will
     * also dump the response object. If the group equals "Generate", then it will loop and send the request
     * with generated attributes until that list is empty.
     *
     * @param file - Request file. Eg. Request-01-Permit.json
     * @param group - This is the parsed out string of the request file that defines if it is a
     *            Permit/Deny/Generate etc.
     * @throws Exception
     */
    protected void sendRequest(Path file, String group) throws Exception {
        logger.info(file.toString());
        int requestCount = 0;
        do {
            //
            // Generate the request
            //
            Request request = this.generateRequest(file, group);
            //
            // Was something generated?
            //
            if (request == null) {
                //
                // Get out of the loop
                //
                logger.info("NULL request generated.");
                break;
            }
            logger.info(request);
            //
            // Call the PDP
            //
            Response response = this.callPDP(request);
            //
            // Process the response
            //
            this.processResponse(file, request, response, group, requestCount);
            //
            // Is this a generated request?
            //
            if (group.equals("Generate")) {
                //
                // Yes, increment counter and move
                // on to the next generated request.
                //
                requestCount++;
            } else {
                //
                // Nope, exit the loop
                //
                break;
            }
        } while (group.equals("Generate"));
    }

    /**
     * Sends the request object to the PDP engine. Either the embedded engine or the RESTful engine.
     *
     * @param request - XACML request object
     * @return Response - returns the XACML response object
     */
    protected Response callPDP(Request request) {
        //
        // Send it to the PDP
        //
        Response response = null;
        if (this.isREST) {
            try {
                String jsonString = JSONRequest.toString(request, false);
                //
                // Call RESTful PDP
                //
                response = this.callRESTfulPDP(new ByteArrayInputStream(jsonString.getBytes()));
            } catch (Exception e) {
                logger.error("Error in sending RESTful request: " + e, e);
            }
        } else {
            //
            // Embedded call to PDP
            //
            long lTimeStart = System.currentTimeMillis();
            try {
                response = this.engine.decide(request);
            } catch (PDPException e) {
                logger.error(e);
            }
            long lTimeEnd = System.currentTimeMillis();
            logger.info("Elapsed Time: " + (lTimeEnd - lTimeStart) + "ms");
        }
        return response;
    }

    /**
     * Reads the request file into a Request object based on its type. If the request has "Generate" in its
     * filename, then this function will add generated attributes into the request.
     *
     * @param file - Request file. Eg. Request-01-Permit.json
     * @param group - This is the parsed out string of the request file that defines if it is a
     *            Permit/Deny/Generate etc.
     * @return
     * @throws org.apache.openaz.xacml.std.json.JSONStructureException
     * @throws org.apache.openaz.xacml.std.dom.DOMStructureException
     * @throws org.apache.openaz.xacml.api.pep.PEPException
     */
    protected Request generateRequest(Path file, String group) throws JSONStructureException,
        DOMStructureException, PEPException {
        //
        // Convert to a XACML Request Object
        //
        Request request = null;
        if (TestBase.isJSON(file)) {
            request = JSONRequest.load(file.toFile());
        } else if (TestBase.isXML(file)) {
            request = DOMRequest.load(file.toFile());
        }
        if (request == null) {
            throw new PEPException("Invalid Request File: " + file.toString());
        }
        //
        // Only if this request has "Generate"
        // Request.XX.Generate.[json|xml]
        //
        if (group.equals("Generate")) {
            //
            // Add attributes to it
            //
            request = this.onNextRequest(request);
        }
        //
        // Done
        //
        return request;
    }

    /**
     * Called to add in generated attributes into the request.
     *
     * @param request
     * @return
     */
    protected Request onNextRequest(Request request) {
        //
        // If we have no generators, just return
        //
        if (this.generators.isEmpty()) {
            return request;
        }
        //
        // Copy the request attributes
        //
        List<StdMutableRequestAttributes> attributes = new ArrayList<StdMutableRequestAttributes>();
        for (RequestAttributes a : request.getRequestAttributes()) {
            attributes.add(new StdMutableRequestAttributes(a));
        }
        //
        // Iterate the generators
        //
        for (Generator generator : this.generators) {
            //
            // Read a row in
            //
            String line = generator.read();
            //
            // Was something read?
            //
            if (line == null) {
                //
                // No more rows to read, return null
                //
                return null;
            }
            //
            // Split the line
            //
            List<String> fields = Lists.newArrayList(Splitter.on(',').trimResults().split(line));
            //
            // Now work on the attributes
            //
            for (StdMutableAttribute attribute : generator.attributes) {
                //
                // Grab the attribute holder, which holds the datatype and field. There should
                // be only ONE object in the collection.
                //
                AttributeValue<?> value = attribute.getValues().iterator().next();
                Integer field = (Integer)value.getValue();
                //
                // Is the field number valid?
                //
                if (field >= fields.size()) {
                    logger.error("Not enough fields: " + field + "(" + fields.size() + ")");
                    return null;
                }
                //
                // Determine what datatype it is
                //
                DataType<?> dataTypeExtended = dataTypeFactory.getDataType(value.getDataTypeId());
                if (dataTypeExtended == null) {
                    logger.error("Failed to determine datatype");
                    return null;
                }
                //
                // Create the attribute value
                //
                try {
                    AttributeValue<?> attributeValue = dataTypeExtended.createAttributeValue(fields
                        .get(field));
                    //
                    // Create the attribute
                    //
                    StdMutableAttribute newAttribute = new StdMutableAttribute(attribute.getCategory(),
                                                                               attribute.getAttributeId(),
                                                                               attributeValue,
                                                                               attribute.getIssuer(),
                                                                               attribute
                                                                                   .getIncludeInResults());
                    boolean added = false;
                    for (StdMutableRequestAttributes a : attributes) {
                        //
                        // Does the category exist?
                        //
                        if (a.getCategory().equals(attribute.getCategory())) {
                            //
                            // Yes - add in the new attribute value
                            //
                            a.add(newAttribute);
                            added = true;
                            break;
                        }
                    }
                    if (!added) {
                        //
                        // New category - create it and add it in
                        //
                        StdMutableRequestAttributes a = new StdMutableRequestAttributes();
                        a.setCategory(newAttribute.getCategory());
                        a.add(newAttribute);
                        attributes.add(a);
                    }
                } catch (DataTypeException e) {
                    logger.error(e);
                    return null;
                }
            }
        }
        //
        // Now form our final request
        //
        StdMutableRequest newRequest = new StdMutableRequest();
        newRequest.setCombinedDecision(request.getCombinedDecision());
        newRequest.setRequestDefaults(request.getRequestDefaults());
        newRequest.setReturnPolicyIdList(request.getReturnPolicyIdList());
        newRequest.setStatus(request.getStatus());
        for (StdMutableRequestAttributes a : attributes) {
            newRequest.add(a);
        }
        return newRequest;
    }

    /**
     * This makes an HTTP POST call to a running PDP RESTful servlet to get a decision.
     *
     * @param file
     * @return
     */
    protected Response callRESTfulPDP(InputStream is) {
        Response response = null;
        HttpURLConnection connection = null;
        try {

            //
            // Open up the connection
            //
            connection = (HttpURLConnection)this.restURL.openConnection();
            connection.setRequestProperty("Content-Type", "application/json");
            //
            // Setup our method and headers
            //
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            //
            // Adding this in. It seems the HttpUrlConnection class does NOT
            // properly forward our headers for POST re-direction. It does so
            // for a GET re-direction.
            //
            // So we need to handle this ourselves.
            //
            connection.setInstanceFollowRedirects(false);
            connection.setDoOutput(true);
            connection.setDoInput(true);
            //
            // Send the request
            //
            try (OutputStream os = connection.getOutputStream()) {
                IOUtils.copy(is, os);
            }
            //
            // Do the connect
            //
            connection.connect();
            if (connection.getResponseCode() == 200) {
                //
                // Read the response
                //
                ContentType contentType = null;
                try {
                    contentType = ContentType.parse(connection.getContentType());

                    if (contentType.getMimeType()
                        .equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) {
                        response = JSONResponse.load(connection.getInputStream());
                    } else if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_XML
                                                                              .getMimeType())
                               || contentType.getMimeType().equalsIgnoreCase("application/xacml+xml")) {
                        response = DOMResponse.load(connection.getInputStream());
                    } else {
                        logger.error("unknown content-type: " + contentType);
                    }

                } catch (Exception e) {
                    String message = "Parsing Content-Type: " + connection.getContentType() + ", error="
                                     + e.getMessage();
                    logger.error(message, e);
                }

            } else {
                logger.error(connection.getResponseCode() + " " + connection.getResponseMessage());
            }
        } catch (Exception e) {
            logger.error(e);
        }

        return response;
    }

    /**
     * This processes a response. Saves the response out to disk. If there is a corresponding response file
     * for the request located in the "responses" sub-directory, then this method will compare that response
     * file with what the engine returned to see if it matched.
     *
     * @param requestFile
     * @param request
     * @param response
     * @param group
     * @param count
     * @throws Exception
     */
    protected void processResponse(Path requestFile, Request request, Response response, String group,
                                   int count) throws Exception {
        //
        // Construct the output filename
        //
        Path responseFile = null;
        Path resultFile = null;
        int num = requestFile.getNameCount();
        if (num < 2) {
            logger.error("Too few dir's in request filename.");
            throw new Exception(
                                "Too few dir's in request filename. Format should be Request.[0-9]+.{Permit|Deny|NA|Indeterminate}.{json|xml}");
        }
        String filename = requestFile.getFileName().toString();
        if (group.equals("Generate")) {
            //
            // Using count variable, construct a filename
            //
            // i.e. Response.03.Generate.{count}.json
            //
            filename = "Response" + filename.substring(filename.indexOf('.'), filename.lastIndexOf('.'))
                       + String.format("%03d", count) + filename.substring(filename.lastIndexOf('.'));
        } else {
            //
            // Construct filename
            //
            filename = "Response" + filename.substring(filename.indexOf('.'));
        }
        //
        // Determine equivalent response file path
        //
        responseFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "responses");
        if (Files.notExists(responseFile)) {
            //
            // Create it
            //
            logger.warn(responseFile.toString() + " does NOT exist, creating...");
            try {
                Files.createDirectories(responseFile);
            } catch (IOException e) {
                logger.error(e);
                throw new Exception("Cannot proceed without an output directory.");
            }
        }
        responseFile = Paths.get(responseFile.toString(), filename);
        //
        // Determine path to write result file
        //
        if (this.output != null) {
            //
            // User specified an output path
            //
            resultFile = this.output;
        } else {
            //
            // Default path
            //
            resultFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "results");
        }
        //
        // Check if the path exists
        //
        if (Files.notExists(resultFile)) {
            //
            // Create it
            //
            logger.warn(resultFile.toString() + " does NOT exist, creating...");
            try {
                Files.createDirectories(resultFile);
            } catch (IOException e) {
                logger.error(e);
                throw new Exception("Cannot proceed without an output directory.");
            }
        }
        //
        // Add the filename to the path
        //
        resultFile = Paths.get(resultFile.toString(), filename);
        //
        // Check if there is an equivalent response in the response
        // directory. If so, compare our response result with that one.
        //
        boolean succeeded = true;
        if (responseFile != null && Files.exists(responseFile)) {
            //
            // Do comparison
            //
            Response expectedResponse = null;
            if (TestBase.isJSON(responseFile)) {
                expectedResponse = JSONResponse.load(responseFile);
            } else if (TestBase.isXML(responseFile)) {
                expectedResponse = DOMResponse.load(responseFile);
            }
            if (expectedResponse != null) {
                //
                // Do the compare
                //
                if (response == null) {
                    logger.error("NULL response returned.");
                    this.responseNotMatches++;
                    succeeded = false;
                } else {
                    if (response.equals(expectedResponse)) {
                        logger.info("Response matches expected response.");
                        this.responseMatches++;
                    } else {
                        logger.error("Response does not match expected response.");
                        logger.error("Expected: ");
                        logger.error(expectedResponse.toString());
                        this.responseNotMatches++;
                        succeeded = false;
                    }
                }
            }
        }
        //
        // Write the response to the result file
        //
        logger.info("Request: " + requestFile.getFileName() + " response is: "
                    + (response == null ? "null" : response.toString()));
        if (resultFile != null && response != null) {
            if (TestBase.isJSON(resultFile)) {
                Files.write(resultFile, JSONResponse.toString(response, true).getBytes());
            } else if (TestBase.isXML(resultFile)) {
                Files.write(resultFile, DOMResponse.toString(response, true).getBytes());
            }
        }
        //
        // Stats
        //
        if (group.equals("Permit")) {
            this.expectedPermits++;
        } else if (group.equals("Deny")) {
            this.expectedDenies++;
        } else if (group.equals("NA")) {
            this.expectedNotApplicables++;
        } else if (group.equals("Indeterminate")) {
            this.expectedIndeterminates++;
        }
        if (response != null) {
            for (Result result : response.getResults()) {
                Decision decision = result.getDecision();
                if (group.equals("Generate")) {
                    if (decision.equals(Decision.PERMIT)) {
                        this.generatedpermits++;
                    } else if (decision.equals(Decision.DENY)) {
                        this.generateddenies++;
                    } else if (decision.equals(Decision.NOTAPPLICABLE)) {
                        this.generatednotapplicables++;
                    } else if (decision.equals(Decision.INDETERMINATE)) {
                        this.generatedindeterminates++;
                    }
                    continue;
                }
                if (decision.equals(Decision.PERMIT)) {
                    this.permits++;
                    if (!group.equals("Permit")) {
                        succeeded = false;
                        logger.error("Expected " + group + " got " + decision);
                    }
                } else if (decision.equals(Decision.DENY)) {
                    this.denies++;
                    if (!group.equals("Deny")) {
                        succeeded = false;
                        logger.error("Expected " + group + " got " + decision);
                    }
                } else if (decision.equals(Decision.NOTAPPLICABLE)) {
                    this.notapplicables++;
                    if (!group.equals("NA")) {
                        succeeded = false;
                        logger.error("Expected " + group + " got " + decision);
                    }
                } else if (decision.equals(Decision.INDETERMINATE)) {
                    this.indeterminates++;
                    if (!group.equals("Indeterminate")) {
                        succeeded = false;
                        logger.error("Expected " + group + " got " + decision);
                    }
                }
            }
        }
        if (succeeded) {
            logger.info("REQUEST SUCCEEDED");
        } else {
            logger.info("REQUEST FAILED");
        }
    }

    protected void dumpStats() {
        StringBuilder dump = new StringBuilder();
        dump.append(System.lineSeparator());
        dump.append("Permits: " + this.permits + " Expected: " + this.expectedPermits);
        dump.append(System.lineSeparator());
        dump.append("Denies: " + this.denies + " Expected: " + this.expectedDenies);
        dump.append(System.lineSeparator());
        dump.append("NA: " + this.notapplicables + " Expected: " + this.expectedNotApplicables);
        dump.append(System.lineSeparator());
        dump.append("Indeterminates: " + this.indeterminates + " Expected: " + this.expectedIndeterminates);
        dump.append(System.lineSeparator());
        dump.append("Generated Permits: " + this.generatedpermits);
        dump.append(System.lineSeparator());
        dump.append("Generated Denies: " + this.generateddenies);
        dump.append(System.lineSeparator());
        dump.append("Generated NA: " + this.generatednotapplicables);
        dump.append(System.lineSeparator());
        dump.append("Generated Indeterminates: " + this.generatedindeterminates);
        dump.append(System.lineSeparator());
        dump.append("Responses Matched: " + this.responseMatches);
        dump.append(System.lineSeparator());
        dump.append("Responses NOT Matched: " + this.responseNotMatches);

        if (this.permits != this.expectedPermits || this.denies != this.expectedDenies
            || this.notapplicables != this.expectedNotApplicables
            || this.indeterminates != this.expectedIndeterminates || this.responseNotMatches > 0) {
            logger.fatal(dump.toString());
        } else {
            logger.info(dump.toString());
        }
    }

    protected void resetStats() {
        this.permits = 0;
        this.denies = 0;
        this.notapplicables = 0;
        this.indeterminates = 0;
        this.generatedpermits = 0;
        this.generateddenies = 0;
        this.generatednotapplicables = 0;
        this.generatedindeterminates = 0;
        this.responseMatches = 0;
        this.responseNotMatches = 0;
    }

    public static void main(String[] args) {
        try {
            new TestBase(args).run();
        } catch (ParseException | IOException | FactoryException e) {
            logger.error(e);
        } catch (HelpException e) {
        }
    }
}
