/*
 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 * $Id: JAXRSClient.java 69819 2013-02-05 12:21:32Z supol $
 */

package com.sun.ts.tests.jaxrs.ee.rs.core.headers;

import java.io.IOException;
import java.text.DateFormat;
import java.util.TimeZone;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Variant;

import com.sun.ts.tests.jaxrs.common.client.JaxrsCommonClient;
import com.sun.ts.tests.jaxrs.common.provider.StringBean;
import com.sun.ts.tests.jaxrs.common.util.JaxrsUtil;

/*
 * @class.setup_props: webServerHost;
 *                     webServerPort;
 *                     ts_home;
 */
public class JAXRSClient extends JaxrsCommonClient {

	private static final long serialVersionUID = -5727774504018187299L;

	public JAXRSClient() {
		setContextRoot("/jaxrs_ee_core_headers_web/HeadersTest");
	}

	/**
	 * 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);
	}

	/* Run test */
	/*
	 * @testName: cookieTest
	 * @assertion_ids: JAXRS:SPEC:3.6;
	 *                 JAXRS:JAVADOC:77;
	 * @test_Strategy: Client invokes GET request on root resource at /HeadersTest/cookie with Cookie set;
	 *                 Verify that all Cookies properties are set by the request
	 */
	public void cookieTest() throws Fault {
		setProperty(Property.REQUEST_HEADERS,
				"Cookie: $Version=1; name1=value1; $Domain=" + _hostname
						+ "; $Path=/jaxrs_ee_core_headers_web");
		setProperty(Property.REQUEST, buildRequest(Request.GET, "cookie"));
		setProperty(Property.SEARCH_STRING,
				"getCookie|Cookie Name=name1|Cookie Value=value1"
						+ "|Cookie Path=/jaxrs_ee_core_headers_web"
						+ "|Cookie Domain=" + "|Cookie Version=1");
		invoke();
	}

	/*
	 * @testName: acceptLanguageTest
	 * @assertion_ids: JAXRS:SPEC:3.6;
	 *                 JAXRS:JAVADOC:75;
	 * @test_Strategy: Client invokes GET request on root resource at 
	 * 				   /HeadersTes/acl with Language Header set;
	 *                 Verify that HttpHeaders got the property set by 
	 *                 the request
	 */
	public void acceptLanguageTest() throws Fault {
		setProperty(Property.REQUEST_HEADERS,
				buildAccept(MediaType.TEXT_PLAIN_TYPE));
		setProperty(Property.REQUEST_HEADERS, "Accept-Language:en-US");
		setProperty(Property.REQUEST, buildRequest(Request.GET, "acl"));
		setProperty(Property.SEARCH_STRING, "Accept-Language|en-US");
		invoke();
	}

	/*
	 * @testName: contentLanguageTest
	 * @assertion_ids: JAXRS:SPEC:3.6;
	 *                 JAXRS:JAVADOC:78;
	 * @test_Strategy: Client invokes PUT request on root resource at 
	 * 					/HeadersTest with Language Header set;
	 *                 Verify that HttpHeaders got the property set by 
	 *                 the request
	 */
	public void contentLanguageTest() throws Fault {
		setProperty(Property.REQUEST_HEADERS,
				buildAccept(MediaType.TEXT_PLAIN_TYPE));
		Variant variant = new Variant(MediaType.WILDCARD_TYPE, "en-US", null);
		Entity<String> entity = Entity.entity("anything", variant);
		setRequestContentEntity(entity);		
		setProperty(Property.REQUEST, buildRequest(Request.PUT, ""));
		setProperty(Property.SEARCH_STRING_IGNORE_CASE,
				"Content-Language|en-US");
		invoke();
	}

	/*
	 * @testName: mediaTypeTest
	 * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:SPEC:33.8;
	 *                 JAXRS:JAVADOC:79;
	 * @test_Strategy: Client invokes GET request on a sub resource at /HeadersTest/mt
	 *                 with Content-Type Header set;
	 *                 Verify that HttpHeaders got the property set by the request
	 */
	public void mediaTypeTest() throws Fault {
		setProperty(Property.REQUEST_HEADERS,
				"Content-Type:application/xml;charset=utf8");
		setProperty(Property.REQUEST, buildRequest(Request.GET, "mt"));
		setProperty(Property.SEARCH_STRING, "getMediaType|application/xml"
				+ "|MediaType size=1|Key charset|Value utf8");
		invoke();
	}

	/*
	 * @testName: mediaTypeAcceptableTest
	 * @assertion_ids: JAXRS:SPEC:3.6;
	 *                 JAXRS:JAVADOC:76;
	 * @test_Strategy: Client invokes GET request on a sub resource at /HeadersTest/amt
	 *                 with Accept MediaType Header set;
	 *                 Verify that HttpHeaders got the property set by the request
	 */
	public void mediaTypeAcceptableTest() throws Fault {
		setProperty(Property.REQUEST_HEADERS,
				"Accept:text/*, text/html, text/html;level=1, */*");
		setProperty(Property.REQUEST, buildRequest(Request.GET, "amt"));
		setProperty(Property.UNORDERED_SEARCH_STRING,
				"getAcceptableMediaTypes|text/*|text/html|text/html|*/*");
		invoke();
	}

	/*
	 * @testName: requestHeadersTest
	 * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:SPEC:33.8; JAXRS:SPEC:40;
	 *                 JAXRS:JAVADOC:80; JAXRS:JAVADOC:81;
	 * @test_Strategy: Client invokes GET request on a sub resource at /HeadersTest/sub2
	 *                 with Accept MediaType and Content-Type Headers set;
	 *                 Verify that HttpHeaders got the property set by the request
	 */
	public void requestHeadersTest() throws Fault {
		setProperty(Property.REQUEST_HEADERS,
				"Accept:text/*, text/html, text/html;level=1, */*");
		setProperty(Property.REQUEST_HEADERS,
				"Content-Type:application/xml;charset=utf8");
		setProperty(Property.REQUEST, buildRequest(Request.GET, "headers"));
		setProperty(Property.SEARCH_STRING, "getRequestHeaders=|Accept:|text/*");
		setProperty(Property.SEARCH_STRING, "text/html|text/html|*/*");
		setProperty(Property.SEARCH_STRING, "Content-Type:|application/xml");
		setProperty(Property.SEARCH_STRING, "charset=utf8");
		invoke();
	}

	/*
	 * @testName: getDateTest
	 * @assertion_ids: JAXRS:JAVADOC:779;
	 * @test_Strategy: Get message date
	 */
	public void getDateTest() throws Fault {
		long currentTime = System.currentTimeMillis();
		DateFormat format = JaxrsUtil.createDateFormat(TimeZone
				.getTimeZone("GMT"));
		String gmt = format.format(currentTime);

		setProperty(Property.REQUEST, buildRequest(Request.POST, "date"));
		setProperty(Property.CONTENT, "getDate");
		setProperty(Property.REQUEST_HEADERS, "Date:" + gmt);
		invoke();
		long responseTime = Long.parseLong(getResponseBody());
		boolean check = Math.abs(currentTime - responseTime) < 1001L;
		assertFault(check, "HttpHeaders.getDate()=", responseTime,
				"differs from expected", currentTime, "by more than 1000 ms.");
		logMsg("#getDate() returned expected Date instance");
	}

	/*
	 * @testName: getHeaderStringTest
	 * @assertion_ids: JAXRS:JAVADOC:780;
	 * @test_Strategy: Get a HTTP header as a single string value.
	 */
	public void getHeaderStringTest() throws Fault {
		String[] headers = { "askdjb", "ksadbva", "klwiaslkfn", "klwvasbk" };
		for (String header : headers) {
			setProperty(Property.REQUEST,
					buildRequest(Request.POST, "headerstring"));
			setProperty(Property.CONTENT, header);
			setProperty(Property.REQUEST_HEADERS, header + ":" + header
					+ header);
			setProperty(Property.SEARCH_STRING, header + header);
			invoke();
		}
		logMsg("#getHeaderString() returned expected header values");
	}

	/*
	 * @testName: getHeaderStringUsesToStringTest
	 * @assertion_ids: JAXRS:JAVADOC:780;
	 * @test_Strategy: Get a HTTP header as a single string value.
	 * 				   Each single header value is converted to String using 
	 * 					its toString method if a header delegate is not available.
	 */
	public void getHeaderStringUsesToStringTest() throws Fault {
		final StringBean bean = new StringBean("bean");
		ClientRequestFilter filter = new ClientRequestFilter() {
			@Override
			public void filter(ClientRequestContext ctx) throws IOException {
				ctx.getHeaders().add(bean.get(), bean);
			}
		};
		setProperty(Property.REQUEST,
				buildRequest(Request.POST, "headerstring"));
		setProperty(Property.CONTENT, bean.get());
		addProvider(filter);
		setProperty(Property.SEARCH_STRING, bean.toString());
		invoke();
		logMsg("#getHeaderString() returned expected header converted by toString() method");
	}

	/*
	 * @testName: getLengthTest
	 * @assertion_ids: JAXRS:JAVADOC:781;
	 * @test_Strategy: Get Content-Length value
	 */
	public void getLengthTest() throws Fault {
		setProperty(Property.REQUEST, buildRequest(Request.GET, "length"));
		invoke();
		String body = getResponseBody();
		assertFault(body != null && body.length() > 0, "Nothing returned");
		long length = Long.parseLong(body);
		assertFault(length != 0, "Nothing returned");
		logMsg("#getLength() returned expected length", body);
	}
}
