/*
 * Copyright (c) 2006, 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 com.sun.s1asdev.security.jmac.soap.client;

import java.util.Map;

import jakarta.jws.HandlerChain;
import jakarta.xml.ws.WebServiceRef;

import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;

import com.sun.s1asdev.security.jmac.soap.ejbws.HelloEjb;
import com.sun.s1asdev.security.jmac.soap.ejbws.JmacSoapEjbService;
import com.sun.s1asdev.security.jmac.soap.servletws.HelloServlet;
import com.sun.s1asdev.security.jmac.soap.servletws.JmacSoapServletService;

public class Client {
    private static SimpleReporterAdapter stat =
            new SimpleReporterAdapter("appserv-tests");
    private static String testSuite = "Sec::Jmac SOAP test ";

    @HandlerChain(file="myhandler.xml")
    @WebServiceRef(wsdlLocation="http://@HOST@:@PORT@/JmacSoapEjbService/HelloEjb?WSDL")
    private static JmacSoapEjbService ejbService;

    @HandlerChain(file="myhandler.xml")
    @WebServiceRef(wsdlLocation="http://@HOST@:@PORT@/security-jmac-soap-web/webservice/JmacSoapServletService/HelloServlet?WSDL")
    private static JmacSoapServletService servletService;


    public static void main(String[] args) {
        stat.addDescription("security-jmac-soap");
        String description = null;
        try {
            HelloEjb ejbPort = ejbService.getHelloEjbPort();

            description = testSuite + " ejbws: hello";
            String ejbMsg = ejbPort.hello("Sun");
            System.out.println(ejbMsg);
            if ("InboundHandler ValResp SecResp HelloEjb ValReq SecReq OutboundHandler Sun".equals(ejbMsg)) {
                stat.addStatus(description, stat.PASS);  
            } else {
                stat.addStatus(description, stat.FAIL);  
            }

            HelloServlet servletPort = servletService.getHelloServletPort();
            description = testSuite + " serlvetws: hello";
            String servletMsg = servletPort.hello("Sun");
            System.out.println(servletMsg);
            if ("InboundHandler ValResp SecResp HelloServlet ValReq SecReq OutboundHandler Sun".equals(servletMsg)) {
                stat.addStatus(description, stat.PASS);  
            } else {
                stat.addStatus(description, stat.FAIL);  
            }
        } catch(Exception ex) {
            ex.printStackTrace();
            stat.addStatus(description, stat.FAIL);
        }

        stat.printSummary("security-jmac-soap");
    }
}
