/*
 *  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) 2013 AT&T Knowledge Ventures
 *              Unpublished and Not for Publication
 *                     All Rights Reserved
 */
package org.apache.openaz.xacml.pdp.std.json;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.openaz.xacml.api.Advice;
import org.apache.openaz.xacml.api.Attribute;
import org.apache.openaz.xacml.api.AttributeCategory;
import org.apache.openaz.xacml.api.IdReference;
import org.apache.openaz.xacml.api.Obligation;
import org.apache.openaz.xacml.api.Response;
import org.apache.openaz.xacml.api.Result;
import org.apache.openaz.xacml.std.dom.DOMResponse;
import org.apache.openaz.xacml.std.json.JSONResponse;
import org.apache.openaz.xacml.util.ListUtil;
import org.junit.Test;

/**
 * Test JSON Response convert to object - Conformance tests TO RUN - use jUnit In Eclipse select this file or
 * the enclosing directory, right-click and select Run As/JUnit Test Note: some of the validation tests
 * comparing the XML-derived Results to the JSON-derived Results are high-level comparisons of Collections.
 * When this class was first created that was sufficient to pass all Conformance tests. However if this sees a
 * failure in a Conformance test, those validations may need to be upgraded to look at the individual data
 * elements to see what is wrong.
 */
public class ResponseConformanceTest {

    // where to find the conformance test XML files
    private final String CONFORMANCE_DIRECTORY_PATH = "testsets/conformance/xacml3.0-ct-v.0.4";

    // The request object output from each test conversion from JSON string
    Response response;

    // test just one of each top-level element.
    // For simple elements also test for incorrect type
    @Test
    public void testConformanceResponses() {

        List<File> filesInDirectory = null;

        File conformanceDirectory = null;

        File currentFile = null;

        try {
            conformanceDirectory = new File(CONFORMANCE_DIRECTORY_PATH);
            filesInDirectory = getRequestsInDirectory(conformanceDirectory);
        } catch (Exception e) {
            fail("Unable to set up Conformance tests for dir '" + conformanceDirectory.getAbsolutePath()
                 + "' e=" + e);
        }

        // run through each XML file
        // - load the file from XML into an internal Response object
        // - generate the JSON representation of that Response object
        // - load that JSON representation into a new Response object
        // - compare the 2 Request objects
        Response xmlResponse = null;
        Response jsonResponse = null;
        try {
            for (File f : filesInDirectory) {
                currentFile = f;

                // // This is a simple way to select just one file for debugging - comment out when not being
                // used
                // if ( ! f.getName().equals("IIIA030Response.xml") && !
                // f.getName().equals("IIIA330Response.xml")) { continue; }

                // during debugging it is helpful to know what file it is starting to work on
                // System.out.println("starting file="+currentFile.getName());

                try {
                    // load XML into a Response object
                    xmlResponse = DOMResponse.load(f);
                } catch (Exception e) {
                    // if XML does not load, just note it and continue with next file
                    System.out.println("XML file did not load: '" + f.getName() + "  e=" + e);
                    continue;
                }

                // some tests have JSON response files to load, most do not
                String jsonFileName = f.getName().replace(".xml", ".json");
                File jsonFile = new File(conformanceDirectory, jsonFileName);

                if (jsonFile.exists()) {
                    // System.out.println("found file "+jsonFile.getName());
                    // json version exists in file, so load it
                    jsonResponse = JSONResponse.load(jsonFile);
                } else {
                    // json does not exist in file, so create it from the XML response using a String
                    // intermediate version
                    String jsonResponseString = JSONResponse.toString(xmlResponse, false);
                    // System.out.println(jsonResponseString);
                    // System.out.println(JSONResponse.toString(xmlResponse, true));

                    jsonResponse = JSONResponse.load(jsonResponseString);
                }

                // System.out.println(JSONResponse.toString(xmlResponse, true));

                // compare the two Response objects

                // compare results
                assertEquals(xmlResponse.getResults().size(), jsonResponse.getResults().size());

                if (xmlResponse.getResults().size() == 0) {
                    fail("neither XML nor JSON response have any Results");
                }

                // Results are an un-ordered Collection.
                // There is no identifying information that is unique to a specific Result.
                // If there are more than one we cannot be sure which one corresponds with which.
                // The best we can do is say that one or more in the first list do not match any in the second
                // list
                if (xmlResponse.getResults().size() > 1) {
                    for (Result xmlResult : xmlResponse.getResults()) {
                        boolean found = false;
                        for (Result jsonResult : jsonResponse.getResults()) {
                            if (xmlResult.equals(jsonResult)) {
                                found = true;
                                break;
                            }
                        }
                        if (found) {
                            continue;
                        }
                        // no match found
                        System.out.println("No match for XML in " + f.getName());
                        System.out.println("XML =" + xmlResult.toString());
                        for (Result jsonResult : jsonResponse.getResults()) {
                            System.out.println("JSON=" + jsonResult.toString());
                        }
                        fail("JSON Response has no match for XML Result: " + xmlResult.toString());
                    }
                    // we've done the best we can for multiple decisions, so go to next file
                    continue;
                }

                // single Result in each
                Result xmlResult = xmlResponse.getResults().iterator().next();
                Result jsonResult = jsonResponse.getResults().iterator().next();

                // The following sections have not given us trouble, so checking is very high-level.
                // If we see a problem in one of these elements, the single line will need to be replaced with
                // detailed examination of the objects.
                assertEquals(f.getName() + " Decision", xmlResult.getDecision(), jsonResult.getDecision());
                assertEquals(f.getName() + " Status", xmlResult.getStatus(), jsonResult.getStatus());

                // Obligations
                if (xmlResult.getObligations() != jsonResult.getObligations()) {
                    Collection<Obligation> xmlObligations = xmlResult.getObligations();
                    Collection<Obligation> jsonObligations = jsonResult.getObligations();
                    // if both are null we do not get here
                    if (xmlObligations == null || jsonObligations == null) {
                        fail(f.getName() + " Obligations has null \nXML=" + xmlObligations + "\nJSON="
                             + jsonObligations);
                    }
                    if (!ListUtil.equalsAllowNulls(xmlObligations, jsonObligations)) {
                        // collections are not equal, so need to examine further
                        fail(f.getName() + " Obligation collections not equal\nXML=" + xmlObligations
                             + "\nJSON=" + jsonObligations);
                    }
                }

                // AssociatedAdvice
                if (xmlResult.getAssociatedAdvice() != jsonResult.getAssociatedAdvice()) {
                    Collection<Advice> xmlAdvice = xmlResult.getAssociatedAdvice();
                    Collection<Advice> jsonAdvice = jsonResult.getAssociatedAdvice();
                    // if both are null we do not get here
                    if (xmlAdvice == null || jsonAdvice == null) {
                        fail(f.getName() + " Advice has null \nXML=" + xmlAdvice + "\nJSON=" + jsonAdvice);
                    }
                    if (!ListUtil.equalsAllowNulls(xmlAdvice, jsonAdvice)) {
                        // collections are not equal, so need to examine further
                        fail(f.getName() + " Advice collections not equal\nXML=" + xmlAdvice + "\nJSON="
                             + jsonAdvice);
                    }
                }

                // check Attributes in more detail
                Collection<AttributeCategory> xmlAttributes = xmlResult.getAttributes();
                Collection<AttributeCategory> jsonAttributes = jsonResult.getAttributes();
                if (xmlAttributes == null && jsonAttributes != null || xmlAttributes != null
                    && jsonAttributes == null) {
                    fail(f.getName() + " XML Attributes=" + xmlAttributes + "  but JSON Attributes="
                         + jsonAttributes);
                }
                if (xmlAttributes != null) {
                    // both are non-null
                    if (xmlAttributes.size() != jsonAttributes.size()) {
                        String xmlAttributesString = "XML categorys=";
                        for (AttributeCategory ac : xmlAttributes) {
                            xmlAttributesString += " " + ac.getCategory().stringValue();
                        }
                        String jsonAttributesString = "JSON categorys=";
                        for (AttributeCategory ac : jsonAttributes) {
                            jsonAttributesString += " " + ac.getCategory().stringValue();
                        }
                        fail(f.getName() + " XML and JSON have different number of Category elements: "
                             + xmlAttributesString + ", " + jsonAttributesString);
                    }

                    // Attribute collections are the same size but may be in different orders.
                    // for each XML category try to find the corresponding JSON category.
                    // ASSUME that each category only shows up once!!!!
                    for (AttributeCategory xmlAttributeCategory : xmlAttributes) {
                        boolean attributeCategoryFound = false;
                        for (AttributeCategory jsonAttributeCategory : jsonAttributes) {
                            if (xmlAttributeCategory.equals(jsonAttributeCategory)) {
                                attributeCategoryFound = true;
                                break;
                            }
                            // not an exact match, but if same CategoryId then need to check individual
                            // Attribute objects
                            if (xmlAttributeCategory.getCategory()
                                .equals(jsonAttributeCategory.getCategory())) {
                                // same category
                                if (xmlAttributeCategory.getAttributes().size() != jsonAttributeCategory
                                    .getAttributes().size()) {
                                    System.out.println("XML =" + xmlAttributeCategory.getAttributes());
                                    System.out.println("JSON=" + jsonAttributeCategory.getAttributes());
                                    fail(f.getName() + " Attributes Category '"
                                         + xmlAttributeCategory.getCategory().stringValue()
                                         + "' size mismatch; XML="
                                         + xmlAttributeCategory.getAttributes().size() + ", JSON="
                                         + jsonAttributeCategory.getAttributes().size());
                                }
                                for (Attribute xmlAttr : xmlAttributeCategory.getAttributes()) {
                                    boolean attributeFound = false;
                                    for (Attribute jsonAttr : jsonAttributeCategory.getAttributes()) {
                                        if (xmlAttr.equals(jsonAttr)) {
                                            attributeFound = true;
                                            break;
                                        }
                                    }

                                    if (attributeFound) {
                                        // check next XML attribute
                                        continue;
                                    }
                                    System.out.println("Attribute not found in JSON, Category="
                                                       + xmlAttributeCategory.getCategory());
                                    System.out.println("XML Attribute =" + xmlAttr);
                                    System.out.println("JSON Attributes=" + jsonAttributeCategory.toString());
                                    fail(f.getName() + " Attribute not found in JSON, Category="
                                         + xmlAttributeCategory.getCategory() + "/nXML Attribute=" + xmlAttr
                                         + "\nJSON Category Attributes=" + jsonAttributeCategory.toString());
                                }

                            }
                        }
                        if (attributeCategoryFound) {
                            continue;
                        }
                        fail("XML Category not found in JSON; xml=" + xmlAttributeCategory.toString());
                    }

                }

                // PolicyIdentifiers
                if (xmlResult.getPolicyIdentifiers() != jsonResult.getPolicyIdentifiers()) {
                    Collection<IdReference> xmlIdReferences = xmlResult.getPolicyIdentifiers();
                    Collection<IdReference> jsonIdReferences = jsonResult.getPolicyIdentifiers();
                    // if both are null we do not get here
                    if (xmlIdReferences == null || jsonIdReferences == null) {
                        fail(f.getName() + " PolicyIdentifiers has null \nXML=" + xmlIdReferences + "\nJSON="
                             + jsonIdReferences);
                    }
                    if (!ListUtil.equalsAllowNulls(xmlIdReferences, jsonIdReferences)) {
                        // collections are not equal, so need to examine further
                        fail(f.getName() + " PolicyIdentifiers collections not equal\nXML=" + xmlIdReferences
                             + "\nJSON=" + jsonIdReferences);
                    }
                }

                // PolicySetIdentifiers
                if (xmlResult.getPolicySetIdentifiers() != jsonResult.getPolicySetIdentifiers()) {
                    Collection<IdReference> xmlIdReferences = xmlResult.getPolicySetIdentifiers();
                    Collection<IdReference> jsonIdReferences = jsonResult.getPolicySetIdentifiers();
                    // if both are null we do not get here
                    if (xmlIdReferences == null || jsonIdReferences == null) {
                        fail(f.getName() + " PolicySetIdentifiers has null \nXML=" + xmlIdReferences
                             + "\nJSON=" + jsonIdReferences);
                    }
                    if (!ListUtil.equalsAllowNulls(xmlIdReferences, jsonIdReferences)) {
                        // collections are not equal, so need to examine further
                        fail(f.getName() + " PolicySetIdentifiers collections not equal\nXML="
                             + xmlIdReferences + "\nJSON=" + jsonIdReferences);
                    }
                }

            }

        } catch (Exception e) {
            fail("Failed test with '" + currentFile.getName() + "', e=" + e);
        }

    }

    //
    // HELPER to get list of all Request files in the given directory
    //

    private List<File> getRequestsInDirectory(File directory) {
        List<File> fileList = new ArrayList<File>();

        File[] fileArray = directory.listFiles();
        for (File f : fileArray) {
            if (f.isDirectory()) {
                List<File> subDirList = getRequestsInDirectory(f);
                fileList.addAll(subDirList);
            }
            if (f.getName().endsWith("Response.xml")) {
                fileList.add(f);
            }
        }
        return fileList;

    }

}

/*
 * This is a place to copy the really long output from test rigs that need to be manually edited for
 * readability....
 * {"Response":[{"Status":{"StatusCode":{"Value":"urn:oasis:names:tc:xacml:1.0:status:ok"}},"Obligations"
 * :[{"Id":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:obligation-1","AttributeAssignment":[
 * {"Value":"assignment1","DataType":"string","AttributeId":
 * "urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:assignment1"},
 * {"Value":{"Namespaces":[{"Namespace":"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
 * },{"Namespace":"http://www.w3.org/2001/XMLSchema-instance","Prefix":"xsi"}],
 * "XPathCategory":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource",
 * "XPath":"//md:records/md:record"}, "DataType":"xpathExpression",
 * "AttributeId":"urn:oasis:names:tc:xacml:2.0:conformance-test:IIIA030:assignment2"
 * }]}],"Decision":"Permit"}]}
 */

