/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package libclasspath2;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.net.URLConnection;
import java.util.Properties;


/**
 * Utility class used by both the server-side and client-side logic in the
 * library/class path tests to help determine whether resources are loaded from
 * the correct places with a variety of packaging and <library-directory> settings.
 *
 * @author tjquinn
 */
public class ResourceHelper {

    private static final String NO_RESOURCE = "NO_RESOURCE";
    private static final String NO_PROPERTY = "NO_PROPERTY";

    public static String find(String resourceName, String propertyName) throws IOException {
        String result;
        URL url = ResourceHelper.class.getResource(resourceName);
        if (url == null) {
            result = NO_RESOURCE;
        } else {
            /*
             * We found the resource.  Load it into a properties object
             * and then look for the requested property.
             */
            InputStream is = null;
            try {
                URLConnection cnx = url.openConnection();
                cnx.setUseCaches(false);

                is = cnx.getInputStream();
                Properties props = new Properties();
                props.load(is);
                String actualValue = props.getProperty(propertyName);
                if (actualValue == null) {
                    result = NO_PROPERTY;
                } else {
                    result = actualValue;
                }
            } finally {
                if (is != null) {
                    is.close();
                }
            }
        }
        return result;
    }

    /**
     * Makes sure that each test of the form <resourceName>:<propertyName>=<expectedValue>
     * passes; that is, that the resource is found, that the property is
     * set by the properties file represented by that resource, and that the
     * property value is the same as the expected value.
     *@param tests 0 or more expressions <resourceName>:<propertyName>=<expectedValue>
     *@return Results object describing the results of the tests
     */
    public static Result checkAll(String[] tests, TestType callerTestType) throws IOException {
        Result result = new Result();
        TestType currentArgumentTestType = TestType.BOTH;
        for (String test : tests) {
            TestType newTestType = null;
            if (test.startsWith("-")) {
                /*
                 * This argument may specify a change in which test type the following tests are.
                 */
                if ((newTestType = TestType.find(test.substring(1))) != null) {
                    currentArgumentTestType = newTestType;
                } else {
                    System.err.println("Did not recognize new test type of " + test + "; ignoring and continuing.");
                }
                continue;
            }

            if ( ! callerTestType.runs(currentArgumentTestType)) {
                continue;
            }
            int colon = test.indexOf(":");
            if (colon <= 0) {
                throw new IllegalArgumentException("Missing : in test " + test);
            }
            int equals = test.indexOf("=");
            if (equals <= colon) {
                throw new IllegalArgumentException("Missing = sign in test " + test);
            }
            String resourceName = test.substring(0,colon);
            String propertyName = test.substring(colon+1, equals);
            String expectedResult = test.substring(equals+1);
            String resultValue = find(resourceName, propertyName);
            if (resultValue.equals(expectedResult)) {
                result.recordResult(true, test + " passed@");
            } else {
                result.recordResult(false, test + " failed (actual " + resultValue + ")@");
            }
        }
        return result;
    }

    public static class Result implements Serializable {
        private boolean result = true;
        private StringBuilder results = new StringBuilder();

        private void recordResult(boolean result, String note) {
            this.result &= result;
            results.append(note).append("@");
        }

        public boolean getResult() {
            return result;
        }

        public StringBuilder getResults() {
            return results;
        }
    }

    public static enum TestType {
        CLIENT("clientonly"),
        SERVER("serveronly"),
        BOTH("both");

        private String name;
        TestType(String name) {
            this.name = name;
        }

        public String toString() {
            return name;
        }

        public static TestType find(String type) {
            for (TestType tt : values()) {
                if (tt.toString().equals(type)) {
                    return tt;
                }
            }
            return null;
        }

        boolean runs(TestType argumentTestType) {
            return argumentTestType.equals(BOTH) || (this.equals(argumentTestType));
        }
    }
}
