package de.itvsh.goofy;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;

import java.time.Instant;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.info.BuildProperties;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import de.itvsh.goofy.common.ModelBuilder;
import de.itvsh.goofy.common.downloadtoken.DownloadTokenController;
import de.itvsh.goofy.common.user.CurrentUserService;
import de.itvsh.goofy.common.user.UserId;
import de.itvsh.goofy.common.user.UserProfileController;
import de.itvsh.goofy.common.user.UserRole;
import de.itvsh.goofy.vorgang.VorgangController;

@RestController
@RequestMapping("/api")
public class RootController {

	static final String REL_VORGAENGE = "vorgaenge";
	static final String REL_SEARCH = "search";
	static final String REL_SEARCH_USER = "search-user-profiles";
	static final String REL_MY_VORGAENGE = "myVorgaenge";
	static final String REL_SEARCH_MY_VORGAENGE = "searchMyVorgaenge";
	static final String REL_DOWNLOAD_TOKEN = "downloadToken";

	@Autowired(required = false)
	public BuildProperties buildProperties;
	@Autowired
	private CurrentUserService currentUserService;

	@GetMapping
	public EntityModel<RootResource> getRootResource() {
		return ModelBuilder.fromEntity(new RootResource())
				.ifMatch(this::hasRole).addLinks(
						linkTo(RootController.class).withSelfRel(),
						linkTo(VorgangController.class).withRel(REL_VORGAENGE),
						linkTo(methodOn(UserProfileController.class).findUsers(null)).withRel(REL_SEARCH_USER),
						linkTo(DownloadTokenController.class).withRel(REL_DOWNLOAD_TOKEN),
						buildVorgangListByPageLink(REL_SEARCH, Optional.empty()))
				.ifMatch(this::hasVerwaltungRole).addLinks(
						buildVorgangListByPageLink(REL_MY_VORGAENGE, Optional.of(currentUserService.getUserId())),
						buildVorgangListByPageLink(REL_SEARCH_MY_VORGAENGE, Optional.of(currentUserService.getUserId())))
				.buildModel();
	}

	boolean hasRole() {
		return hasVerwaltungRole() || currentUserService.hasRole(UserRole.EINHEITLICHER_ANSPRECHPARTNER);
	}

	boolean hasVerwaltungRole() {
		return currentUserService.hasRole(UserRole.VERWALTUNG_USER)
				|| currentUserService.hasRole(UserRole.VERWALTUNG_POSTSTELLE);
	}

	private Link buildVorgangListByPageLink(String linkRel, Optional<UserId> assignedTo) {
		return linkTo(methodOn(VorgangController.class).getVorgangListByPage(0, null, null, assignedTo)).withRel(linkRel);
	}

	class RootResource {

		public String getVersion() {
			return buildProperties == null ? "--" : buildProperties.getVersion();
		}

		public Instant getBuildTime() {
			return buildProperties == null ? null : buildProperties.getTime();
		}

		public String getJavaVersion() {
			return System.getProperty("java.version");
		}
	}
}