/*

   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.

 */
package org.apache.batik.test.svg;

import java.io.File;
import java.io.FilePermission;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Enumeration;

import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.bridge.BaseScriptingEnvironment;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.BridgeException;
import org.apache.batik.bridge.DefaultExternalResourceSecurity;
import org.apache.batik.bridge.DefaultScriptSecurity;
import org.apache.batik.bridge.EmbededExternalResourceSecurity;
import org.apache.batik.bridge.EmbededScriptSecurity;
import org.apache.batik.bridge.ExternalResourceSecurity;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.NoLoadExternalResourceSecurity;
import org.apache.batik.bridge.NoLoadScriptSecurity;
import org.apache.batik.bridge.RelaxedExternalResourceSecurity;
import org.apache.batik.bridge.RelaxedScriptSecurity;
import org.apache.batik.bridge.ScriptSecurity;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.test.AbstractTest;
import org.apache.batik.test.TestReport;
import org.apache.batik.util.ApplicationSecurityEnforcer;
import org.apache.batik.util.ParsedURL;
import org.apache.batik.util.XMLResourceDescriptor;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * This test takes an SVG file as an input. It processes the input SVG
 * (meaning it turns it into a GVT tree) and then dispatches the 'onload'
 * event.
 *
 * In that process, the test checks for the occurence of a specific
 * exception type and, for BridgeExceptions, for a given error code.
 *
 * If an exception of the given type (and, optionally, code) happens,
 * then the test passes. If an exception of an unexpected type
 * (or code, for BridgeExceptions) happens, or if no exception happens,
 * the test fails.
 *
 * The following properties control the test's operation:
 * - Scripts: list of allowed script types (e.g., "application/java-archive")
 * - ScriptOrigin: "ANY", "DOCUMENT", "EMBEDED", "NONE"
 * - ResourceOrigin: "ANY", "DOCUMENT", "EMBEDED", "NONE"
 * - ExpectedExceptionClass (e.g., "java.lang.SecurityException")
 * - ExpectedErrorCode (e.g., "err.uri.unsecure")
 * - Validate (e.g., "true")
 *
 * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a>
 * @version $Id$
 */
public class SVGOnLoadExceptionTest extends AbstractTest {
    /**
     * Value for the script having successfully run.
     */
    public static final String RAN = "ran";

    /**
     * Error when the expected exception did not occur
     */
    public static final String ERROR_EXCEPTION_DID_NOT_OCCUR
        = "SVGOnLoadExceptionTest.error.exception.did.not.occur";

    /**
     * Error when an exception occured, but not of the expected
     * class
     */
    public static final String ERROR_UNEXPECTED_EXCEPTION
        = "SVGOnLoadExceptionTest.error.unexpected.exception";

    /**
     * Error when a BridgeException occured, as expected, but
     * with an unexpected error code
     */
    public static final String ERROR_UNEXPECTED_ERROR_CODE
        = "SVGOnLoadExceptionTest.error.unexpected.error.code";

    /**
     * Error when the script does not run as expected.
     */
    public static final String ERROR_SCRIPT_DID_NOT_RUN
        = "SVGOnLoadExceptionTest.error.script.did.not.run";

    /**
     * Entry describing the unexpected exception
     */
    public static final String ENTRY_KEY_UNEXPECTED_EXCEPTION
        = "SVGOnLoadExceptionTest.entry.key.unexpected.exception";

    /**
     * Entry describing the unexpected error code
     */
    public static final String ENTRY_KEY_UNEXPECTED_ERROR_CODE
        = "SVGOnLoadExceptionTest.entry.key.unexpected.error.code";

    /**
     * Entry describign the expected error code
     */
    public static final String ENTRY_KEY_EXPECTED_ERROR_CODE
        = "SVGOnLoadExceptionTest.entry.key.expected.error.code";

    /**
     * Entry describing the expected exception
     */
    public static final String ENTRY_KEY_EXPECTED_EXCEPTION
        = "SVGOnLoadExceptionTest.entry.key.expected.exception";

    /**
     * Entry describing the unexpected exception
     */
    public static final String ENTRY_KEY_UNEXPECTED_RESULT
        = "SVGOnLoadExceptionTest.entry.key.unexpected.result";

    /**
     * Value used to disable error code check on BridgeExceptions
     */
    public static final String ERROR_CODE_NO_CHECK
        = "noCheck";

    /**
     * Test Namespace
     */
    public static final String testNS = "http://xml.apache.org/batik/test";

    /**
     * The URL for the input SVG document to be tested
     */
    protected String svgURL;

    /**
     * The allowed script types
     */
    protected String scripts = "text/ecmascript, application/java-archive";

    /**
     * Name of the expected exception class
     */
    protected String expectedExceptionClass = "org.apache.batik.bridge.Exception";

    /**
     * Expected error code (for BridgeExceptions)
     */
    protected String expectedErrorCode = "none";

    /**
     * The allowed script origin
     */
    protected String scriptOrigin = "ANY";

    /**
     * The allowed external resource origin
     */
    protected String resourceOrigin = "ANY";

    /**
     * True if the scripts are run securely (i.e., with a security manager)
     */
    protected boolean secure = false;

    /**
     * Controls whether or not the input SVG document should be validated
     */
    protected Boolean validate = Boolean.FALSE;

    /**
     * The name of the test file
     */
    protected String fileName;

    /**
     * Controls whether on not the document should be processed from
     * a 'restricted' context, one with no createClassLoader permission.
     */
    protected boolean restricted = false;

    public boolean getRestricted() {
        return restricted;
    }

    public void setRestricted(boolean restricted) {
        this.restricted = restricted;
    }

    public void setScripts(String scripts){
        this.scripts = scripts;
    }

    public String getScripts(){
        return scripts;
    }

    public void setScriptOrigin(String scriptOrigin){
        this.scriptOrigin = scriptOrigin;
    }

    public String getScriptOrigin(){
        return this.scriptOrigin;
    }

    public void setResourceOrigin(String resourceOrigin){
        this.resourceOrigin = resourceOrigin;
    }

    public String getResourceOrigin(){
        return this.resourceOrigin;
    }

    public void setSecure(boolean secure){
        this.secure = secure;
    }

    public boolean getSecure(){
        return secure;
    }

    public void setExpectedExceptionClass(String expectedExceptionClass){
        this.expectedExceptionClass = expectedExceptionClass;
    }

    public String getExpectedExceptionClass(){
        return this.expectedExceptionClass;
    }

    public void setExpectedErrorCode(String expectedErrorCode){
        this.expectedErrorCode = expectedErrorCode;
    }

    public String getExpectedErrorCode(){
        return this.expectedErrorCode;
    }

    public Boolean getValidate() {
        return validate;
    }

    public void setValidate(Boolean validate) {
        this.validate = validate;
        if (this.validate == null) {
            this.validate = Boolean.FALSE;
        }
    }

    /**
     * Default constructor
     */
    public SVGOnLoadExceptionTest(){
    }

    public void setId(String id){
        super.setId(id);

        if (id != null) {
            int i = id.indexOf("(");
            if (i != -1) {
                id = id.substring(0, i);
            }
            fileName = "test-resources/org/apache/batik/" + id + ".svg";
            svgURL = resolveURL(fileName);
        }
    }

    /**
     * Resolves the input string as follows.
     * + First, the string is interpreted as a file description.
     *   If the file exists, then the file name is turned into
     *   a URL.
     * + Otherwise, the string is supposed to be a URL. If it
     *   is an invalid URL, an IllegalArgumentException is thrown.
     */
    protected String resolveURL(String url){
        // Is url a file?
        File f = (new File(url)).getAbsoluteFile();
        if(f.getParentFile().exists()){
            try{
                return f.toURI().toURL().toString();
            }catch(MalformedURLException e){
                throw new IllegalArgumentException();
            }
        }

        // url is not a file. It must be a regular URL...
        try{
            return (new URL(url)).toString();
        }catch(MalformedURLException e){
            throw new IllegalArgumentException(url);
        }
    }


    /**
     * Run this test and produce a report.
     * The test goes through the following steps: <ul>
     * <li>load the input SVG into a Document</li>
     * <li>build the GVT tree corresponding to the
     *     Document and dispatch the 'onload' event</li>
     * </ul>
     *
     */
    public TestReport runImpl() throws Exception{
        ApplicationSecurityEnforcer ase
            = new ApplicationSecurityEnforcer(this.getClass(),
                                              "org/apache/batik/apps/svgbrowser/resources/svgbrowser.policy");

        if (secure) {
            ase.enforceSecurity(true);
        }

        try {
            if (!restricted) {
                return testImpl();
            } else {
                // Emulate calling from restricted code. We create a
                // calling context with only the permission to read
                // the file.
                Policy policy = Policy.getPolicy();
                URL classesURL = (new File("classes")).toURI().toURL();
                CodeSource cs = new CodeSource(classesURL, (Certificate[])null);
                PermissionCollection permissionsOrig
                    = policy.getPermissions(cs);
                Permissions permissions = new Permissions();
                Enumeration iter = permissionsOrig.elements();
                while (iter.hasMoreElements()) {
                    Permission p = (Permission)iter.nextElement();
                    if (!(p instanceof RuntimePermission)) {
                        if (!(p instanceof java.security.AllPermission)) {
                            permissions.add(p);
                        }
                    } else {
                        if (!"createClassLoader".equals(p.getName())) {
                            permissions.add(p);
                        }
                    }
                }

                fileName = new File(fileName).getAbsolutePath();
                permissions.add(new FilePermission(fileName, "read"));
                permissions.add(new RuntimePermission("accessDeclaredMembers"));

                ProtectionDomain domain;
                AccessControlContext ctx;
                domain = new ProtectionDomain(null, permissions);
                ctx = new AccessControlContext(new ProtectionDomain[]{domain});

                try {
                    return (TestReport)AccessController.doPrivileged
                        (new PrivilegedExceptionAction() {
                                public Object run() throws Exception {
                                    return testImpl();
                                }
                            }, ctx);
                } catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
        } finally {
            ase.enforceSecurity(false);
        }
    }

    /**
     * Implementation helper
     */
    protected TestReport testImpl() {
        //
        // First step:
        //
        // Load the input SVG into a Document object
        //
        String parserClassName = XMLResourceDescriptor.getXMLParserClassName();
        SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parserClassName);
        f.setValidating(validate);
        Document doc = null;

        try {
            doc = f.createDocument(svgURL);
        } catch(Exception e){
            e.printStackTrace();
            return handleException(e);
        }

        //
        // Second step:
        //
        // Now that the SVG file has been loaded, build
        // a GVT Tree from it
        //
        TestUserAgent userAgent = buildUserAgent();
        GVTBuilder builder = new GVTBuilder();
        BridgeContext ctx = new BridgeContext(userAgent);
        ctx.setDynamic(true);
        Exception e = null;
        try {
            builder.build(ctx, doc);
            BaseScriptingEnvironment scriptEnvironment
                = new BaseScriptingEnvironment(ctx);
            scriptEnvironment.loadScripts();
            scriptEnvironment.dispatchSVGLoadEvent();
        } catch (Exception ex){
            e = ex;
        } finally {
            if (e == null && userAgent.e != null) {
                e = userAgent.e;
            }

            if (e != null) {
                return handleException(e);
            }
        }

        //
        // If we got here, it means that an exception did not
        // happen. Check if this is expected.
        TestReport report = null;
        if (expectedExceptionClass == null) {
            // No error was expected then check that the script ran.
            Element elem = doc.getElementById("testResult");
            String s = elem.getAttributeNS(null, "result");
            if (RAN.equals(s)) {
                report = reportSuccess();
            } else {
                report = reportError(ERROR_SCRIPT_DID_NOT_RUN);
                report.addDescriptionEntry(ENTRY_KEY_UNEXPECTED_RESULT,
                                           s);
            }
        }
        if (report == null) {
            report = reportError(ERROR_EXCEPTION_DID_NOT_OCCUR);
            report.addDescriptionEntry(ENTRY_KEY_EXPECTED_EXCEPTION,
                                       expectedExceptionClass);
        }
        return report;
    }

    /**
     * Compares the input exception with the expected exception
     * If they match, then the test passes. Otherwise, the test fails
     */
    protected TestReport handleException(Exception e) {
        if (!isMatch(e.getClass(), expectedExceptionClass)) {
            TestReport report = reportError(ERROR_UNEXPECTED_EXCEPTION);
            report.addDescriptionEntry(ENTRY_KEY_UNEXPECTED_EXCEPTION,
                                       e.getClass().getName());
            report.addDescriptionEntry(ENTRY_KEY_EXPECTED_EXCEPTION,
                                       expectedExceptionClass);
            return report;
        } else {
            if (!ERROR_CODE_NO_CHECK.equals(expectedErrorCode)
                && e instanceof BridgeException) {
                if ( !expectedErrorCode.equals(((BridgeException)e).getCode()) ) {
                    TestReport report = reportError(ERROR_UNEXPECTED_ERROR_CODE);
                    report.addDescriptionEntry(ENTRY_KEY_UNEXPECTED_ERROR_CODE,
                                               ((BridgeException)e).getCode());
                    report.addDescriptionEntry(ENTRY_KEY_EXPECTED_ERROR_CODE,
                                               expectedErrorCode);
                    return report;
                }
            }
            return reportSuccess();
        }
    }

    /**
     * Check if the input class' name (or one of its base classes) matches
     * the input name.
     */
    protected boolean isMatch(final Class cl, final String name) {
        if (cl == null) {
            return false;
        } else if (cl.getName().equals(name)) {
            return true;
        } else {
            return isMatch(cl.getSuperclass(), name);
        }
    }

    /**
     * Give subclasses a chance to build their own UserAgent
     */
    protected TestUserAgent buildUserAgent(){
        return new TestUserAgent();
    }

    class TestUserAgent extends UserAgentAdapter {
        Exception e;

        public ExternalResourceSecurity
            getExternalResourceSecurity(ParsedURL resourceURL,
                                        ParsedURL docURL) {
            if ("ANY".equals(resourceOrigin)) {
                return new RelaxedExternalResourceSecurity(resourceURL,
                                                           docURL);
            } else if ("DOCUMENT".equals(resourceOrigin)) {
                return new DefaultExternalResourceSecurity(resourceURL,
                                                           docURL);
            } else if ("EMBEDED".equals(resourceOrigin)) {
                return new EmbededExternalResourceSecurity(resourceURL);
            } else {
                return new NoLoadExternalResourceSecurity();
            }
        }

        public ScriptSecurity
            getScriptSecurity(String scriptType,
                              ParsedURL scriptURL,
                              ParsedURL docURL) {
            ScriptSecurity result = null;
            if (scripts.indexOf(scriptType) == -1) {
                result = new NoLoadScriptSecurity(scriptType);
            } else {
                if ("ANY".equals(scriptOrigin)) {
                    result = new RelaxedScriptSecurity(scriptType,
                                                     scriptURL,
                                                     docURL);
                } else if ("DOCUMENT".equals(scriptOrigin)) {
                    result = new DefaultScriptSecurity(scriptType,
                                                     scriptURL,
                                                     docURL);
                } else if ("EMBEDED".equals(scriptOrigin)) {
                    result = new EmbededScriptSecurity(scriptType,
                                                     scriptURL,
                                                     docURL);
                } else {
                    result = new NoLoadScriptSecurity(scriptType);
                }
            }
            return result;
        }

        public void displayError(Exception e) {
            this.e = e;
        }
    }

}
