// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.rest.annotation;

import org.apache.juneau.jsonschema.annotation.ExternalDocs;
import org.apache.juneau.http.annotation.*;

/**
 * Extended annotation for {@link Rest#swagger() @Rest(swagger)}.
 *
 * <ul class='seealso'>
 * 	<li class='link'>{@doc juneau-rest-server.Swagger}
 * </ul>
 */
public @interface ResourceSwagger {


	/**
	 * Defines the swagger field <c>/info/title</c>.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=<ja>@ResourceSwagger</ja>(
	 * 			title=<js>"Petstore application"</js>
	 * 		)
	 * 	)
	 * </p>
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is plain-text.
	 * 		<br>Multiple lines are concatenated with newlines.
	 * 	<li>
	 * 		The precedence of lookup for this field is:
	 * 		<ol>
	 * 			<li><c>{resource-class}.title</c> property in resource bundle.
	 * 			<li>{@link ResourceSwagger#title()} on this class, then any parent classes.
	 * 			<li>Value defined in Swagger JSON file.
	 * 			<li>{@link Rest#title()} on this class, then any parent classes.
	 * 		</ol>
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * </ul>
	 */
	String[] title() default {};

	/**
	 * Defines the swagger field <c>/info/description</c>.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=<ja>@ResourceSwagger</ja>(
	 * 			description={
	 * 				<js>"This is a sample server Petstore server based on the Petstore sample at Swagger.io."</js>,
	 * 				<js>"You can find out more about Swagger at &lt;a class='link' href='http://swagger.io'&gt;http://swagger.io&lt;/a&gt;."</js>
	 * 			}
	 * 		)
	 * 	)
	 * </p>
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is plain text.
	 * 		<br>Multiple lines are concatenated with newlines.
	 * 	<li>
	 * 		The precedence of lookup for this field is:
	 * 		<ol>
	 * 			<li><c>{resource-class}.description</c> property in resource bundle.
	 * 			<li>{@link ResourceSwagger#description()} on this class, then any parent classes.
	 * 			<li>Value defined in Swagger JSON file.
	 * 			<li>{@link Rest#description()} on this class, then any parent classes.
	 * 		</ol>
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * </ul>
	 */
	String[] description() default {};

	/**
	 * Defines the swagger field <c>/info/contact</c>.
	 *
	 * <p>
	 * A {@doc SimpleJson} string with the following fields:
	 * <p class='bcode w800'>
	 * 	{
	 * 		name: string,
	 * 		url: string,
	 * 		email: string
	 * 	}
	 * </p>
	 *
	 * <p>
	 * The default value pulls the description from the <c>contact</c> entry in the servlet resource bundle.
	 * (e.g. <js>"contact = {name:'John Smith',email:'john.smith@foo.bar'}"</js> or
	 * <js>"MyServlet.contact = {name:'John Smith',email:'john.smith@foo.bar'}"</js>).
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=<ja>@MethodSwagger</ja>(
	 * 			contact=<js>"{name:'John Smith',email:'john.smith@foo.bar'}"</js>
	 * 		)
	 * 	)
	 * </p>
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is a {@doc SimpleJson} object.
	 * 		<br>Multiple lines are concatenated with newlines.
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * </ul>
	 */
	Contact contact() default @Contact;

	/**
	 * Defines the swagger field <c>/externalDocs</c>.
	 *
	 * <p>
	 * It is used to populate the Swagger external documentation field and to display on HTML pages.
	 * 	 *
	 * <p>
	 * The default value pulls the description from the <c>externalDocs</c> entry in the servlet resource bundle.
	 * (e.g. <js>"externalDocs = {url:'http://juneau.apache.org'}"</js> or
	 * <js>"MyServlet.externalDocs = {url:'http://juneau.apache.org'}"</js>).
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=<ja>@MethodSwagger</ja>(
	 * 			externalDocs=<ja>@ExternalDocs</ja>(url=<js>"http://juneau.apache.org"</js>)
	 * 		)
	 * 	)
	 * </p>
	 */
	ExternalDocs externalDocs() default @ExternalDocs;

	/**
	 * Defines the swagger field <c>/info/license</c>.
	 *
	 * <p>
	 * It is used to populate the Swagger license field and to display on HTML pages.
	 *
	 * <p>
	 * A {@doc SimpleJson} string with the following fields:
	 * <p class='bcode w800'>
	 * 	{
	 * 		name: string,
	 * 		url: string
	 * 	}
	 * </p>
	 *
	 * <p>
	 * The default value pulls the description from the <c>license</c> entry in the servlet resource bundle.
	 * (e.g. <js>"license = {name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js> or
	 * <js>"MyServlet.license = {name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>).
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=<ja>@MethodSwagger</ja>(
	 * 			license=<js>"{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>
	 * 		)
	 * 	)
	 * </p>
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is a {@doc SimpleJson} object.
	 * 		<br>Multiple lines are concatenated with newlines.
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * </ul>
	 */
	License license() default @License;

	/**
	 * Defines the swagger field <c>/tags</c>.
	 *
	 *
	 * Optional tagging information for the exposed API.
	 *
	 * <p>
	 * It is used to populate the Swagger tags field and to display on HTML pages.
	 *
	 * <p>
	 * A {@doc SimpleJson} string with the following fields:
	 * <p class='bcode w800'>
	 * 	[
	 * 		{
	 * 			name: string,
	 * 			description: string,
	 * 			externalDocs: {
	 * 				description: string,
	 * 				url: string
	 * 			}
	 * 		}
	 * 	]
	 * </p>
	 *
	 * <p>
	 * The default value pulls the description from the <c>tags</c> entry in the servlet resource bundle.
	 * (e.g. <js>"tags = [{name:'Foo',description:'Foobar'}]"</js> or
	 * <js>"MyServlet.tags = [{name:'Foo',description:'Foobar'}]"</js>).
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=<ja>@MethodSwagger</ja>(
	 * 			tags=<js>"[{name:'Foo',description:'Foobar'}]"</js>
	 * 		)
	 * 	)
	 * </p>
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is a {@doc SimpleJson} array.
	 * 		<br>Multiple lines are concatenated with newlines.
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * </ul>
	 */
	Tag[] tags() default {};

	/**
	 * Defines the swagger field <c>/info/termsOfService</c>.
	 *
	 *
	 * Optional servlet terms-of-service for this API.
	 *
	 * <p>
	 * It is used to populate the Swagger terms-of-service field.
	 *
	 * <p>
	 * The default value pulls the description from the <c>termsOfService</c> entry in the servlet resource bundle.
	 * (e.g. <js>"termsOfService = foo"</js> or <js>"MyServlet.termsOfService = foo"</js>).
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is plain text.
	 * 		<br>Multiple lines are concatenated with newlines.
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * </ul>
	 */
	String[] termsOfService() default {};

	/**
	 * Defines the swagger field <c>/info/version</c>.
	 *
	 *
	 *
	 * Provides the version of the application API (not to be confused with the specification version).
	 *
	 * <p>
	 * It is used to populate the Swagger version field and to display on HTML pages.
	 *
	 * <p>
	 * The default value pulls the description from the <c>version</c> entry in the servlet resource bundle.
	 * (e.g. <js>"version = 2.0"</js> or <js>"MyServlet.version = 2.0"</js>).
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is plain text.
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * </ul>
	 */
	String version() default "";

	/**
	 * Free-form value for the swagger of a resource.
	 *
	 * <p>
	 * This is a {@doc SimpleJson} object that makes up the swagger information for this resource.
	 *
	 * <p>
	 * The following are completely equivalent ways of defining the swagger description of a resource:
	 * <p class='bcode w800'>
	 * 	<jc>// Normal</jc>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=<ja>@ResourceSwagger</ja>(
	 * 			title=<js>"Petstore application"</js>,
	 * 			description={
	 * 				<js>"This is a sample server Petstore server based on the Petstore sample at Swagger.io."</js>,
	 * 				<js>"You can find out more about Swagger at &lt;a class='link' href='http://swagger.io'&gt;http://swagger.io&lt;/a&gt;."</js>
	 * 			},
	 * 			contact=<ja>@Contact</ja>(
	 * 				name=<js>"John Smith"</js>,
	 * 				email=<js>"john@smith.com"</js>
	 * 			),
	 * 			license=<ja>@License</ja>(
	 * 				name=<js>"Apache 2.0"</js>,
	 * 				url=<js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>
	 * 			),
	 * 			version=<js>"2.0"</js>,
	 * 			termsOfService=<js>"You are on your own."</js>,
	 * 			tags={
	 * 				<ja>@Tag</ja>(
	 * 					name=<js>"Java"</js>,
	 * 					description=<js>"Java utility"</js>,
	 * 					externalDocs=<ja>@ExternalDocs</ja>(
	 * 						description=<js>"Home page"</js>,
	 * 						url=<js>"http://juneau.apache.org"</js>
	 * 					)
	 * 				}
	 * 			},
	 * 			externalDocs=<ja>@ExternalDocs</ja>(
	 * 				description=<js>"Home page"</js>,
	 * 				url=<js>"http://juneau.apache.org"</js>
	 * 			)
	 * 		)
	 * 	)
	 * </p>
	 * <p class='bcode w800'>
	 * 	<jc>// Free-form</jc>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=@ResourceSwagger({
	 * 			<js>"title: 'Petstore application',"</js>,
	 * 			<js>"description: 'This is a sample server Petstore server based on the Petstore sample at Swagger.io.\nYou can find out more about Swagger at &lt;a class='link' href='http://swagger.io'&gt;http://swagger.io&lt;/a&gt;.',"</js>,
	 * 			<js>"contact:{"</js>,
	 * 				<js>"name: 'John Smith',"</js>,
	 * 				<js>"email: 'john@smith.com'"</js>,
	 * 			<js>"},"</js>,
	 * 			<js>"license:{"</js>,
	 * 				<js>"name: 'Apache 2.0',"</js>,
	 * 				<js>"url: 'http://www.apache.org/licenses/LICENSE-2.0.html'"</js>,
	 * 			<js>"},"</js>,
	 * 			<js>"version: '2.0',"</js>,
	 * 			<js>"termsOfService: 'You are on your own.',"</js>,
	 * 			<js>"tags:["</js>,
	 * 				<js>"{"</js>,
	 * 					<js>"name: 'Java',"</js>,
	 * 					<js>"description: 'Java utility',"</js>,
	 * 					<js>"externalDocs:{"</js>,
	 * 						<js>"description: 'Home page',"</js>,
	 * 						<js>"url: 'http://juneau.apache.org'"</js>,
	 * 					<js>"}"</js>,
	 * 				<js>"}"</js>,
	 * 			<js>"],"</js>,
	 * 			<js>"externalDocs:{"</js>,
	 * 				<js>"description: 'Home page',"</js>,
	 * 				<js>"url: 'http://juneau.apache.org'"</js>,
	 * 			<js>"}"</js>
	 * 		})
	 * 	)
	 * </p>
	 * <p class='bcode w800'>
	 * 	<jc>// Free-form with variables</jc>
	 * 	<ja>@Rest</ja>(
	 * 		swagger=@ResourceSwagger(<js>"$F{MyResourceSwagger.json}"</js>)
	 * 	)
	 * </p>
	 *
	 * <p>
	 * 	The reasons why you may want to use this field include:
	 * <ul>
	 * 	<li>You want to pull in the entire Swagger JSON definition for this body from an external source such as a properties file.
	 * 	<li>You want to add extra fields to the Swagger documentation that are not officially part of the Swagger specification.
	 * </ul>
	 *
	 * <ul class='notes'>
	 * 	<li>
	 * 		The format is a {@doc SimpleJson} object.
	 * 	<li>
	 * 		The leading/trailing <c>{ }</c> characters are optional.
	 * 		<br>The following two example are considered equivalent:
	 * 		<p class='bcode w800'>
	 * 	<ja>@ResourceSwagger</ja>(<js>"{title:'Petstore application'}"</js>)
	 * 		</p>
	 * 		<p class='bcode w800'>
	 * 	<ja>@ResourceSwagger</ja>(<js>"title:'Petstore application'"</js>)
	 * 		</p>
	 * 	<li>
	 * 		Multiple lines are concatenated with newlines so that you can format the value to be readable.
	 * 	<li>
	 * 		Supports {@doc DefaultRestSvlVariables}
	 * 		(e.g. <js>"$L{my.localized.variable}"</js>).
	 * 	<li>
	 * 		Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation.
	 * </ul>
	 */
	String[] value() default {};
}
