/*
 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 * $Id: JAXRSClient.java 73544 2014-02-26 09:22:57Z supol $
 */
package com.sun.ts.tests.jaxrs.api.rs.webapplicationexceptiontest;

import java.io.IOException;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.sun.ts.lib.util.TestUtil;
import com.sun.ts.tests.jaxrs.common.JAXRSCommonClient;

/*
 * WebApplicationException tests are also at ee/resource/webappexception/nomapper
 */
public class JAXRSClient extends JAXRSCommonClient {

	private static final long serialVersionUID = 8214271241869777148L;
	private static final Status STATUS = Status.INTERNAL_SERVER_ERROR;
	protected static final String MESSAGE = "TCK WebApplicationException description";
	protected static final String HOST = "www.jcp.org";

	public JAXRSClient() {
		setContextRoot("/jaxrs_api_rs_webapplicationexceptiontest_web");
	}

	/**
	 * Entry point for different-VM execution. It should delegate to method
	 * run(String[], PrintWriter, PrintWriter), and this method should not
	 * contain any test configuration.
	 */
	public static void main(String[] args) {
		new JAXRSClient().run(args);
	}

	/*
	 * @class.setup_props: webServerHost;
	 *                     webServerPort;
	 *                     ts_home;
	 */
	/* Run test */

	/*
	 * @testName: statusNullTest
	 * @assertion_ids: JAXRS:JAVADOC:16;
	 * @test_Strategy: Verify that WebApplicationException(Status Null) works.
	 */
	public void statusNullTest() throws Fault {
		Response.Status st = null;
		try {
			WebApplicationException e = new WebApplicationException(st);
			throw new Fault("No exception thrown.  Test FAILED", e);
		} catch (IllegalArgumentException ilex) {
			TestUtil.logTrace("Expected exception caught.  Test PASSED");
		} catch (Throwable th) {
			throw new Fault("Wrong exception caught.  Test FAILED",
					th.getCause());
		}
	}

	/*
	 * @testName: throwableStatusTest1
	 * @assertion_ids: JAXRS:JAVADOC:20;
	 * @test_Strategy: Verify that WebApplicationException(Throwable, Status Null) works.
	 */
	public void throwableStatusTest1() throws Fault {
		Response.Status st = null;
		try {
			WebApplicationException e = new WebApplicationException(
					new Throwable(
							"CTS-WebApplicationExceptionTest-throwableStatusTest1-FAIL"),
					st);
			throw new Fault("No exception thrown.  Test FAILED", e);
		} catch (IllegalArgumentException ilex) {
			TestUtil.logTrace("Expected exception thrown.  Test PASS");
		} catch (Throwable th) {
			throw new Fault("Wrong-Exception", th.getCause());
		}
	}

	/*
	 * @testName: constructorStringTest
	 * @assertion_ids: JAXRS:JAVADOC:1111;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance with a blank message and 
	 * 					default HTTP status code of 500.
	 * 					
	 * 					getResponse
	 */
	public void constructorStringTest() throws Fault {
		WebApplicationException e = new WebApplicationException(MESSAGE);
		assertResponse(e, STATUS);
		assertMessage(e);
	}

	/*
	 * @testName: constructorStringResponseTest
	 * @assertion_ids: JAXRS:JAVADOC:1112;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance using the supplied response.
	 * 					
	 * 					getResponse
	 */
	public void constructorStringResponseTest() throws Fault {
		for (Status status : Status.values()) {
			Response response = buildResponse(status);
			WebApplicationException e = new WebApplicationException(MESSAGE,
					response);
			assertResponse(e, status, HOST);
			assertMessage(e);
		}
	}

	/*
	 * @testName: constructorStringNullResponseTest
	 * @assertion_ids: JAXRS:JAVADOC:1112;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance using the supplied response.
	 * 					a value of null will be replaced with an internal 
	 * 					server error response (status code 500).
	 * 
	 * 					getResponse
	 */
	public void constructorStringNullResponseTest() throws Fault {
		WebApplicationException e = new WebApplicationException(MESSAGE,
				(Response) null);
		assertResponse(e, STATUS);
		assertMessage(e);
	}

	/*
	 * @testName: constructorStringIntTest
	 * @assertion_ids: JAXRS:JAVADOC:1113;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance with a message and 
	 * 					specified HTTP status code.
	 * 					
	 * 					getResponse
	 */
	public void constructorStringIntTest() throws Fault {
		for (Status status : Status.values()) {
			WebApplicationException e = new WebApplicationException(MESSAGE,
					status.getStatusCode());
			assertResponse(e, status);
			assertMessage(e);
		}
	}

	/*
	 * @testName: constructorStringStatusTest
	 * @assertion_ids: JAXRS:JAVADOC:1114;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance with a message and 
	 * 					specified HTTP status code.
	 * 					
	 * 					getResponse
	 */
	public void constructorStringStatusTest() throws Fault {
		for (Status status : Status.values()) {
			WebApplicationException e = new WebApplicationException(MESSAGE,
					status);
			assertResponse(e, status);
			assertMessage(e);
		}
	}

	/*
	 * @testName: constructorStringNullStatusThrowsIAETest
	 * @assertion_ids: JAXRS:JAVADOC:1114;
	 * @test_Strategy:  Throws java.lang.IllegalArgumentException 
	 * 					- if status is null.
	 */
	public void constructorStringNullStatusThrowsIAETest() throws Fault {
		try {
			WebApplicationException e = new WebApplicationException(MESSAGE,
					(Status) null);
			fault("No IllegalArgumentException has been thrown, built expcetion is",
					e);
		} catch (IllegalArgumentException e) {
			logMsg("IllegalArgumentException has been thrown as expected when",
					"null Status");
		}
	}

	/*
	 * @testName: constructorStringThrowableTest
	 * @assertion_ids: JAXRS:JAVADOC:1115;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance with a message and 
	 * 					default HTTP status code of 500.
	 * 					
	 * 					getResponse
	 */
	public void constructorStringThrowableTest() throws Fault {
		Throwable[] throwables = new Throwable[] { new RuntimeException(),
				new IOException(), new Error(), new Throwable() };
		for (Throwable t : throwables) {
			WebApplicationException e = new WebApplicationException(MESSAGE, t);
			assertResponse(e, STATUS);
			assertMessage(e);
			assertCause(e, t);
		}
	}

	/*
	 * @testName: constructorStringThrowableResponseTest
	 * @assertion_ids: JAXRS:JAVADOC:1116;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance using the supplied response. 
	 * 					
	 * 					getResponse
	 */
	public void constructorStringThrowableResponseTest() throws Fault {
		Throwable[] throwables = new Throwable[] { new RuntimeException(),
				new IOException(), new Error(), new Throwable() };
		for (Status status : Status.values()) {
			Response response = buildResponse(status);
			for (Throwable t : throwables) {
				WebApplicationException e = new WebApplicationException(
						MESSAGE, t, response);
				assertResponse(e, status, HOST);
				assertMessage(e);
				assertCause(e, t);
			}
		}
	}

	/*
	 * @testName: constructorStringThrowableNullResponseTest
	 * @assertion_ids: JAXRS:JAVADOC:1116;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance using the supplied response. 
	 *					a value of null will be replaced with an internal server
	 *					 error response (status code 500). 					
	 * 
	 * 					getResponse
	 */
	public void constructorStringThrowableNullResponseTest() throws Fault {
		Throwable[] throwables = new Throwable[] { new RuntimeException(),
				new IOException(), new Error(), new Throwable() };
		for (Throwable t : throwables) {
			WebApplicationException e = new WebApplicationException(MESSAGE, t,
					(Response) null);
			assertResponse(e, STATUS);
			assertMessage(e);
			assertCause(e, t);
		}
	}

	/*
	 * @testName: constructorStringThrowableIntTest
	 * @assertion_ids: JAXRS:JAVADOC:1117;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance with a message and specified 
	 * 					HTTP status code. 
	 * 					
	 * 					getResponse
	 */
	public void constructorStringThrowableIntTest() throws Fault {
		Throwable[] throwables = new Throwable[] { new RuntimeException(),
				new IOException(), new Error(), new Throwable() };
		for (Status status : Status.values()) {
			for (Throwable t : throwables) {
				WebApplicationException e = new WebApplicationException(
						MESSAGE, t, status.getStatusCode());
				assertResponse(e, status);
				assertMessage(e);
				assertCause(e, t);
			}
		}
	}

	/*
	 * @testName: constructorStringThrowableStatusTest
	 * @assertion_ids: JAXRS:JAVADOC:1118;
	 * 					JAXRS:JAVADOC:12;
	 * @test_Strategy:  Construct a new instance with a message and specified 
	 * 					HTTP status code. 
	 * 					
	 * 					getResponse
	 */
	public void constructorStringThrowableStatusTest() throws Fault {
		Throwable[] throwables = new Throwable[] { new RuntimeException(),
				new IOException(), new Error(), new Throwable() };
		for (Status status : Status.values()) {
			for (Throwable t : throwables) {
				WebApplicationException e = new WebApplicationException(
						MESSAGE, t, status);
				assertResponse(e, status);
				assertMessage(e);
				assertCause(e, t);
			}
		}
	}

	/*
	 * @testName: constructorStringThrowableNullStatusThrowsIAETest
	 * @assertion_ids: JAXRS:JAVADOC:1118;
	 * @test_Strategy:  Throws java.lang.IllegalArgumentException 
	 * 					- if status is null.
	 */
	public void constructorStringThrowableNullStatusThrowsIAETest()
			throws Fault {
		Throwable[] throwables = new Throwable[] { new RuntimeException(),
				new IOException(), new Error(), new Throwable() };
		for (Throwable t : throwables) {
			try {
				WebApplicationException e = new WebApplicationException(
						MESSAGE, t, (Status) null);
				fault("IllegalArgumentException has not been thrown, exception:",
						e);
			} catch (IllegalArgumentException e) {
				logMsg("IllegalArgumentException has been thrown when",
						"null Status as expected");
			}
		}
	}

	// /////////////////////////////////////////////////////////////
	protected Response buildResponse(Status status) {
		return Response.status(status).header(HttpHeaders.HOST, HOST).build();
	}

	protected static void assertResponse(WebApplicationException e,
			Status status) throws Fault {
		assertNotNull(e.getResponse(), "#getResponse is null");
		Response response = e.getResponse();
		assertEqualsInt(response.getStatus(), status.getStatusCode(),
				"response contains unexpected status", response.getStatus(),
				"response:", response);
		logMsg("response contains expected", status, "status");
	}

	/**
	 * Check the given exception contains a prebuilt response containing the
	 * http header HOST
	 */
	protected void assertResponse(WebApplicationException e, Status status,
			String host) throws Fault {
		assertResponse(e, status);
		String header = e.getResponse().getHeaderString(HttpHeaders.HOST);
		assertNotNull(header, "http header", HttpHeaders.HOST,
				" of response is null");
		assertEquals(host, header, "Found unexpected http", HttpHeaders.HOST,
				"header", header);
		logMsg("Found expected http", HttpHeaders.HOST, "header");
	}

	protected static void assertCause(WebApplicationException e,
			Throwable expected) throws Fault {
		assertEquals(e.getCause(), expected,
				"#getCause does not contain expected", expected, "but",
				e.getCause());
		logMsg("getCause contains expected", expected);
	}

	protected static void assertMessage(WebApplicationException e) throws Fault {
		assertNotNull(e.getMessage(), "getMessage() is null");
		assertContains(e.getMessage(), MESSAGE, "Unexpected getMessage()",
				e.getMessage());
		logMsg("found expected getMessage()=", e.getMessage());
	}
}
