/*
 * Copyright (c) 2009, 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 remoteview;

import javax.ejb.*;
import javax.annotation.*;
import java.util.concurrent.Future;

@Stateless(mappedName="HH")
@RemoteHome(HelloHome.class)
@Remote(Hello.class)
@TransactionManagement(TransactionManagementType.BEAN)
public class HelloBean {

    @Resource
	private SessionContext sessionCtx;

    @PostConstruct
    public void init() {
	System.out.println("In HelloBean::init()");
    }

    public String hello() {
	System.out.println("In HelloBean::hello()");
	return "hello, world\n";
    }

    @Asynchronous
    public Future<String> helloAsync() {
	System.out.println("In HelloBean::helloAsync()");
	return new AsyncResult<String>("helo, async world!\n");
    }

    @Asynchronous
    public Future<String> asyncBlock(int seconds) {
	System.out.println("In HelloBean::asyncBlock");
	sleep(seconds);
	return new AsyncResult<String>("blocked successfully");
    }

    @Asynchronous 
    public void fireAndForget() {
	System.out.println("In HelloBean::fireAndForget()");
	sleep(5);
    }
	
    @Asynchronous 
    public Future<String> asyncThrowException(String exceptionType) {
	System.out.println("In HelloBean::asyncThrowException");
	throwException(exceptionType);
	return new AsyncResult<String>("should have thrown exception");
    }

    @Asynchronous 
    public Future<String> asyncCancel(int seconds) throws Exception
    {
	System.out.println("In HelloBean::asyncCancel");
	sleep(seconds);
	if( sessionCtx.wasCancelCalled() ) {
	    throw new Exception("Canceled after " + seconds + " seconds");
	}
	return new AsyncResult<String>("asyncCancel() should have been cancelled");
    }

    public void throwException(String exceptionType) {
	if( exceptionType.equals("javax.ejb.EJBException") ) {
	    throw new EJBException(exceptionType);
	} else if( exceptionType.equals("javax.ejb.ConcurrentAccessException") ) {
	    throw new ConcurrentAccessException(exceptionType);
	} else if( exceptionType.equals("javax.ejb.ConcurrentAccessTimeoutException") ) {
	    throw new ConcurrentAccessTimeoutException(exceptionType);
	} else if( exceptionType.equals("javax.ejb.IllegalLoopbackException") ) {
	    throw new IllegalLoopbackException(exceptionType);
	}

	throw new IllegalArgumentException(exceptionType);
    }

    private void sleep(int seconds) {

	System.out.println("In HelloBean::sleeping for " + seconds + 
			   "seconds");
	try {
	    Thread.currentThread().sleep(seconds * 1000);
	    System.out.println("In HelloBean::woke up from " + seconds + 
			       "second sleep");
	} catch(Exception e) {
	    e.printStackTrace();
	}

    }


    @PreDestroy
    public void destroy() {
	System.out.println("In HelloBean::destroy()");
    }


}
