// ***************************************************************************************************************************
// * 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.petstore.rest;

import static org.apache.juneau.dto.swagger.ui.SwaggerUI.*;
import static org.apache.juneau.http.HttpMethod.*;
import static org.apache.juneau.http.response.Ok.*;

import java.util.*;
import java.util.Map;

import javax.inject.*;

import org.apache.juneau.jsonschema.annotation.*;
import org.apache.juneau.petstore.*;
import org.apache.juneau.petstore.dto.*;
import org.apache.juneau.petstore.service.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.html.annotation.*;
import org.apache.juneau.http.annotation.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.http.exception.*;
import org.apache.juneau.rest.helper.*;
import org.apache.juneau.http.response.*;
import org.apache.juneau.rest.widget.*;
import org.apache.juneau.transforms.*;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.apache.juneau.rest.converters.*;

/**
 * Sample Petstore application.
 *
 * <ul class='seealso'>
 * 	<li class='extlink'>{@source}
 * </ul>
 */
@Rest(
	path="/petstore",
	title="Petstore application",
	description={
		"This is a sample server Petstore server based on the Petstore sample at Swagger.io.",
		"You can find out more about Swagger at http://swagger.io.",
	},
	properties= {
		// Resolve recursive references when showing schema info in the swagger.
		@Property(name=SWAGGERUI_resolveRefsMaxDepth, value="99")
	},
	swagger=@ResourceSwagger(
		version="1.0.0",
		title="Swagger Petstore",
		termsOfService="You are on your own.",
		contact=@Contact(
			name="Juneau Development Team",
			email="dev@juneau.apache.org",
			url="http://juneau.apache.org"
		),
		license=@License(
			name="Apache 2.0",
			url="http://www.apache.org/licenses/LICENSE-2.0.html"
		),
		externalDocs=@ExternalDocs(
			description="Find out more about Juneau",
			url="http://juneau.apache.org"
		),
		tags={
			@Tag(
				name="pet",
				description="Everything about your Pets",
				externalDocs=@ExternalDocs(
					description="Find out more",
					url="http://juneau.apache.org"
				)
			),
			@Tag(
				name="store",
				description="Access to Petstore orders"
			),
			@Tag(
				name="user",
				description="Operations about user",
				externalDocs=@ExternalDocs(
					description="Find out more about our store",
					url="http://juneau.apache.org"
				)
			)
		}
	),
	debug="true",
	staticFiles={"htdocs:/htdocs"}  // Expose static files in htdocs subpackage.
)
@HtmlDocConfig(
	widgets={
		ContentTypeMenuItem.class,
		ThemeMenuItem.class,
	},
	navlinks={
		"up: request:/..",
		"options: servlet:/?method=OPTIONS",
		"$W{ContentTypeMenuItem}",
		"$W{ThemeMenuItem}",
		"source: $C{Source/gitHub}/org/apache/juneau/petstore/rest/$R{servletClassSimple}.java"
	},
	head={
		"<link rel='icon' href='$U{servlet:/htdocs/cat.png}'/>"  // Add a cat icon to the page.
	},
	header={
		"<h1>$R{resourceTitle}</h1>",
		"<h2>$R{methodSummary}</h2>",
		"$C{PetStore/headerImage}"
	},
	aside={
		"<div style='max-width:400px' class='text'>",
		"	<p>This page shows a standard nested REST resource.</p>",
		"	<p>It shows how different properties can be rendered on the same bean in different views.</p>",
		"	<p>It also shows examples of HtmlRender classes and @BeanProperty(format) annotations.</p>",
		"	<p>It also shows how the Queryable converter and query widget can be used to create searchable interfaces.</p>",
		"</div>"
	},
	stylesheet="servlet:/htdocs/themes/dark.css"  // Use dark theme by default.
)
public class PetStoreResource extends BasicRest implements PetStore {

	@Inject
	private PetStoreService store;

	/**
	 * Navigation page
	 *
	 * @return Navigation page contents.
	 */
	@RestMethod(
		name=GET,
		path="/",
		summary="Navigation page"
	)
	@HtmlDocConfig(
		style={
			"INHERIT",  // Flag for inheriting resource-level CSS.
			"body { ",
				"background-image: url('petstore/htdocs/background.jpg'); ",
				"background-color: black; ",
				"background-size: cover; ",
				"background-attachment: fixed; ",
			"}"
		}
	)
	public ResourceDescriptions getTopPage() {
		return new ResourceDescriptions()
			.append("pet", "All pets in the store")
			.append("store", "Orders and inventory")
			.append("user", "Petstore users")
		;
	}

	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	// Pets
	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/pet",
		summary="All pets in the store",
		swagger=@MethodSwagger(
			tags="pet",
			parameters={
				Queryable.SWAGGER_PARAMS  // Documents searching.
			}
		),
		converters={Queryable.class}  // Searching support.
	)
	@BeanConfig(
		bpx="Pet: tags,photo"  // In this view, don't serialize tags/photos properties.
	)
	public Collection<Pet> getPets() throws NotAcceptable {
		return store.getPets();
	}

	@Override /* PetStore */
	@CrossOrigin(origins = "http://localhost:3000", maxAge = 3600)
	@RestMethod(
		name=GET,
		path="/pet/{petId}",
		summary="Find pet by ID",
		description="Returns a single pet",
		swagger=@MethodSwagger(
			tags="pet"
		)
	)
	public Pet getPet(long petId) throws IdNotFound, NotAcceptable {
		return store.getPet(petId);
	}

	@Override /* PetStore */
	@RestMethod(
		name=POST,
		path="/pet",
		summary="Add a new pet to the store",
		swagger=@MethodSwagger(
			tags="pet"
		)
		//roleGuard="ROLE_ADMIN || (ROLE_USER && ROLE_WRITABLE)"  // Restrict access to this method.
	)
	public long createPet(CreatePet pet) throws IdConflict, NotAcceptable, UnsupportedMediaType {
		return store.create(pet).getId();
	}

	@Override /* PetStore */
	@RestMethod(
		name=PUT,
		path="/pet/{petId}",
		summary="Update an existing pet",
		swagger=@MethodSwagger(
			tags="pet"
		)
	)
	public Ok updatePet(UpdatePet pet) throws IdNotFound, NotAcceptable, UnsupportedMediaType {
		store.update(pet);
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/pet/findByStatus",
		summary="Finds Pets by status",
		description="Multiple status values can be provided with comma separated strings.",
		swagger=@MethodSwagger(
			tags="pet"
		)
	)
	public Collection<Pet> findPetsByStatus(PetStatus[] status) throws NotAcceptable {
		return store.getPetsByStatus(status);
	}

	@Override /* PetStore */
	@RestMethod(
		name=DELETE,
		path="/pet/{petId}",
		summary="Deletes a pet",
		swagger=@MethodSwagger(
			tags="pet"
		)
	)
	public Ok deletePet(String apiKey, long petId) throws IdNotFound, NotAcceptable {
		store.deletePet(petId);
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=DELETE,
		path="/pets",
		summary="Delete all pets",
		description="This can be done only by the logged in user."
	)
	public Ok deleteAllPets() {
		store.deleteAllPets();
		return OK;
	}

	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	// Orders
	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * Store navigation page.
	 *
	 * @return Store navigation page contents.
	 */
	@RestMethod(
		summary="Store navigation page",
		swagger=@MethodSwagger(
			tags="store"
		)
	)
	public ResourceDescriptions getStore() {
		return new ResourceDescriptions()
			.append("store/order", "Petstore orders")
			.append("store/inventory", "Petstore inventory")
		;
	}

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/store/order",
		summary="Petstore orders",
		swagger=@MethodSwagger(
			tags="store"
		)
	)
	@HtmlDocConfig(
		widgets={
			QueryMenuItem.class
		},
		navlinks={
			"INHERIT",                // Inherit links from class.
			"[2]:$W{QueryMenuItem}",  // Insert QUERY link in position 2.
			"[3]:$W{AddOrderMenuItem}"  // Insert ADD link in position 3.
		}
	)
	public Collection<Order> getOrders() throws NotAcceptable {
		return store.getOrders();
	}

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/store/order/{orderId}",
		summary="Find purchase order by ID",
		description="Returns a purchase order by ID.",
		swagger=@MethodSwagger(
			tags="store"
		)
	)
	public Order getOrder(long orderId) throws InvalidId, IdNotFound, NotAcceptable {
		if (orderId < 1 || orderId > 1000)
			throw new InvalidId();
		return store.getOrder(orderId);
	}

	@Override /* PetStore */
	@RestMethod(
		name=POST,
		path="/store/order",
		summary="Place an order for a pet",
		swagger=@MethodSwagger(
			tags="store"
		),
		pojoSwaps={
			TemporalDateSwap.IsoLocalDate.class
		}
	)
	public long placeOrder(long petId, String username) throws IdConflict, NotAcceptable, UnsupportedMediaType {
		CreateOrder co = new CreateOrder(petId, username);
		return store.create(co).getId();
	}

	@Override /* PetStore */
	@RestMethod(
		name=DELETE,
		path="/store/order/{orderId}",
		summary="Delete purchase order by ID",
		description= {
			"For valid response try integer IDs with positive integer value.",
			"Negative or non-integer values will generate API errors."
		},
		swagger=@MethodSwagger(
			tags="store"
		)
	)
	public Ok deleteOrder(long orderId) throws InvalidId, IdNotFound, NotAcceptable {
		if (orderId < 0)
			throw new InvalidId();
		store.deleteOrder(orderId);
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=DELETE,
		path="/orders",
		summary="Delete all orders",
		description="This can be done only by the logged in user."
	)
	public Ok deleteAllOrders() {
		store.deleteAllOrders();
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/store/inventory",
		summary="Returns pet inventories by status",
		description="Returns a map of status codes to quantities",
		swagger=@MethodSwagger(
			tags="store",
			responses={
				"200:{ 'x-example':{AVAILABLE:123} }",
			}
		)
	)
	public Map<PetStatus,Integer> getStoreInventory() throws NotAcceptable {
		return store.getInventory();
	}

	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	// Users
	//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/user",
		summary="Petstore users",
		bpx="User: email,password,phone",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public Collection<User> getUsers() throws NotAcceptable {
		return store.getUsers();
	}

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/user/{username}",
		summary="Get user by user name",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public User getUser(String username) throws InvalidUsername, IdNotFound, NotAcceptable {
		return store.getUser(username);
	}

	@Override /* PetStore */
	@RestMethod(
		name=POST,
		path="/user",
		summary="Create user",
		description="This can only be done by the logged in user.",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public Ok createUser(User user) throws InvalidUsername, IdConflict, NotAcceptable, UnsupportedMediaType {
		store.create(user);
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=POST,
		path="/user/createWithArray",
		summary="Creates list of users with given input array",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public Ok createUsers(User[] users) throws InvalidUsername, IdConflict, NotAcceptable, UnsupportedMediaType {
		for (User user : users)
			store.create(user);
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=PUT,
		path="/user/{username}",
		summary="Update user",
		description="This can only be done by the logged in user.",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public Ok updateUser(String username, User user) throws InvalidUsername, IdNotFound, NotAcceptable, UnsupportedMediaType {
		store.update(user);
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=DELETE,
		path="/user/{username}",
		summary="Delete user",
		description="This can only be done by the logged in user.",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public Ok deleteUser(String username) throws InvalidUsername, IdNotFound, NotAcceptable {
		store.deleteUser(username);
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=DELETE,
		path="/users",
		summary="Delete all users",
		description="This can be done only by the admin."
	)
	public Ok deleteAllUsers() {
		store.deleteAllUsers();
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/user/login",
		summary="Logs user into the system",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public Ok login(
			String username,
			String password,
			Value<Integer> rateLimit,
			Value<ExpiresAfter> expiresAfter
		) throws InvalidLogin, NotAcceptable {

		RestRequest req = getRequest();

		if (! store.isValid(username, password))
			throw new InvalidLogin();

		Date d = new Date(System.currentTimeMillis() + 30 * 60 * 1000);
		req.getSession().setAttribute("login-expires", d);
		rateLimit.set(1000);
		expiresAfter.set(new ExpiresAfter(d));
		return OK;
	}

	@Override /* PetStore */
	@RestMethod(
		name=GET,
		path="/user/logout",
		summary="Logs out current logged in user session",
		swagger=@MethodSwagger(
			tags="user"
		)
	)
	public Ok logout() throws NotAcceptable {
		getRequest().getSession().removeAttribute("login-expires");
		return OK;
	}
}