/**
 * 
 */
package de.bstly.board.controller;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;

import de.bstly.board.businesslogic.EntryManager;
import de.bstly.board.businesslogic.TagManager;
import de.bstly.board.businesslogic.UserManager;
import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.controller.support.RequestBodyErrors;
import de.bstly.board.controller.validation.EntryValidator;
import de.bstly.board.model.Entry;

/**
 * The Class TagController.
 */
@RestController
@RequestMapping("/tags")
public class TagController extends BaseController {

	@Autowired
	private TagManager tagManager;
	@Autowired
	private EntryManager entryManager;
	@Autowired
	private UserManager userManager;
	@Autowired
	private EntryValidator entryValidator;

	/**
	 * Search.
	 *
	 * @param query the query
	 * @return the list
	 */
	@PreAuthorize("isAuthenticated()")
	@GetMapping
	public List<String> search(@RequestParam("q") String query) {
		return tagManager.search(query);
	}

	/**
	 * Sets the tags.
	 *
	 * @param id the id
	 * @param tags the tags
	 * @param ignoreParameter the ignore parameter
	 * @return the entry
	 */
	@PreAuthorize("isAuthenticated()")
	@PatchMapping("/entry/{id}")
	public Entry setTags(@PathVariable("id") Long id, @RequestBody List<String> tags,
			@RequestParam("ignore") Optional<List<String>> ignoreParameter) {
		Entry entry = entryManager.get(id);
		if (entry == null || !entry.getAuthor().equals(getCurrentUsername())) {
			throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
		}

		entry.setTags(tags);

		RequestBodyErrors bindingResult = new RequestBodyErrors(entry);
		entryValidator.validate(entry, bindingResult);

		if (bindingResult.hasErrors()) {
			throw new EntityResponseStatusException(bindingResult.getAllErrors(),
					HttpStatus.UNPROCESSABLE_ENTITY);
		}

		entry = entryManager.save(entry);

		List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
		entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
				entry, ignore);
		return entry;
	}

}
