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

import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Base64.Encoder;

class TestRoleAssignment {

    private static SimpleReporterAdapter stat =
            new SimpleReporterAdapter("appserv-tests");
    private boolean result = true;
    private final String url;
    private final String username;
    private final String password;
    private final String role;
    private final boolean positiveTest;

    public TestRoleAssignment(String url, String username, String password, String role, boolean positiveTest) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.role = role;
        this.positiveTest = positiveTest;
    }

    public void doTest() {
        try {
            URL u = new URL(url);
            URLConnection uconn = u.openConnection();

            up = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8));
            uconn.setRequestProperty("authorization", "Basic " + up);

            try (BufferedReader reader = new BufferedReader(new InputStreamReader(uconn.getInputStream()))) {
                while (reader.readLine() != null) {
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = false;
        }

        stat.addDescription("Weblogic Role Assignment test for role: " + role);
        String testId = "Weblogic Role Assignment test for role: " + role;
        if (positiveTest) {
            if (result) {
                stat.addStatus(testId, stat.PASS);
            } else {
                stat.addStatus(testId, stat.FAIL);
            }
        } else { // negative test
            if (result) {
                stat.addStatus(testId, stat.FAIL);
            } else {
                stat.addStatus(testId, stat.PASS);
            }
        }
        stat.printSummary(testId);
    }
    public static final String URL_OPTION = "-url";
    public static final String USER_OPTION = "-user";
    public static final String PASS_OPTION = "-pass";
    public static final String ROLE_OPTION = "-role";
    public static final String NEGATIVE_TEST_OPTION = "-negative";

    public static void usage() {
        System.out.println("usage: java TestRoleAssignment -url <url> -user <user> -pass <pass> -role <role>");
    }

    public static void main(String[] args) {

        String url = null;
        String user = null;
        String pass = null;
        String role = null;
        boolean positiveTest = true;

        for (int i = 0; i < args.length; i++) {
            if (args[i].intern() == URL_OPTION.intern()) {
                url = args[++i];
            } else if (args[i].intern() == USER_OPTION.intern()) {
                user = args[++i];
            } else if (args[i].intern() == PASS_OPTION.intern()) {
                pass = args[++i];
            } else if (args[i].intern() == ROLE_OPTION.intern()) {
                role = args[++i];
            } else if (args[i].intern() == NEGATIVE_TEST_OPTION.intern()) {
                positiveTest = false;
            } else {
                usage();
                System.exit(1);
            }
        }

        if (url == null || user == null || pass == null || role == null) {
            usage();
            System.exit(1);
        }

        TestRoleAssignment test =
                new TestRoleAssignment(url, user, pass, role, positiveTest);
        test.doTest();
    }
}
