package uk.ac.ebi.biosamples.service;

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

import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.ResourceAssembler;
import org.springframework.hateoas.mvc.ControllerLinkBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import uk.ac.ebi.biosamples.controller.SampleCurationLinksRestController;
import uk.ac.ebi.biosamples.controller.SampleRestController;
import uk.ac.ebi.biosamples.model.Sample;

/**
 * This class is used by Spring to add HAL _links for {@Link Sample} objects.
 * 
 * @author faulcon
 *
 */
@Service
public class SampleResourceAssembler implements ResourceAssembler<Sample, Resource<Sample>> {
	
	public static final String REL_CURATIONDOMAIN="curationDomain";
	public static final String REL_CURATIONLINKS="curationLinks";
	public static final String REL_CURATIONLINK="curationLink";
	
	public SampleResourceAssembler() {
	}

	private Link getSelfLink(String accession, Optional<Boolean> legacydetails, Optional<List<String>> curationDomains) {
    	UriComponentsBuilder uriComponentsBuilder = ControllerLinkBuilder.linkTo(SampleRestController.class, accession).toUriComponentsBuilder();
    	if (legacydetails.isPresent() && legacydetails.get()) {
    		uriComponentsBuilder.queryParam("legacydetails", legacydetails);
    	}
    	if (curationDomains != null && curationDomains.isPresent()) {
    		if (curationDomains.get().size() == 0) {
    			uriComponentsBuilder.queryParam("curationdomain", (Object[])null);
    		} else {
        		for (String curationDomain : curationDomains.get()) {
        			uriComponentsBuilder.queryParam("curationdomain", curationDomain);
        		}
    		}
    	}
    	return new Link(uriComponentsBuilder.build().toUriString(), Link.REL_SELF);
    }
    
    private Link getCurationDomainLink(Link selfLink) {
		UriComponents selfUriComponents = UriComponentsBuilder.fromUriString(selfLink.getHref()).build();
		if (selfUriComponents.getQueryParams().size() == 0) {
			return new Link(selfLink.getHref()+"{?curationdomain}", REL_CURATIONDOMAIN);
		} else {
			return new Link(selfLink.getHref()+"{&curationdomain}", REL_CURATIONDOMAIN);
		}
    }
    
    private Link getCurationLinksLink(String accession) {
    	return ControllerLinkBuilder.linkTo(
			ControllerLinkBuilder.methodOn(SampleCurationLinksRestController.class)
				.getCurationLinkPageJson(accession, null, null)).withRel("curationLinks");
    }
    
    public Resource<Sample> toResource(Sample sample, Optional<Boolean> legacydetails, Optional<List<String>> curationDomains) {
		Resource<Sample> sampleResource = new Resource<>(sample);
		sampleResource.add(getSelfLink(sample.getAccession(), legacydetails, curationDomains));
		//add link to select curation domain
		sampleResource.add(getCurationDomainLink(sampleResource.getLink(Link.REL_SELF)));				
		//add link to curationLinks on this sample
		sampleResource.add(getCurationLinksLink(sample.getAccession()));
		return sampleResource;
    }
    
	@Override
	public Resource<Sample> toResource(Sample sample) {
		Resource<Sample> resource = new Resource<>(sample);
		
		resource.add(ControllerLinkBuilder.linkTo(SampleRestController.class, sample.getAccession()).withSelfRel());
							
		resource.add(ControllerLinkBuilder.linkTo(
				ControllerLinkBuilder.methodOn(SampleCurationLinksRestController.class)
					.getCurationLinkPageJson(sample.getAccession(), null, null)).withRel("curationLinks"));
		resource.add(ControllerLinkBuilder.linkTo(
				ControllerLinkBuilder.methodOn(SampleCurationLinksRestController.class)
					.getCurationLinkJson(sample.getAccession(), null)).withRel("curationLink"));
		
		return resource;
	}
    

}
@@ -2582,32 +2582,285 @@
 onLinks%22);%0A    %7D
+%0A%0A    %0A    private Link getCurationLinkLink(String accession) %7B%0A%09%09return ControllerLinkBuilder.linkTo(%0A%09%09%09%09ControllerLinkBuilder.methodOn(SampleCurationLinksRestController.class)%0A%09%09%09%09%09.getCurationLinkJson(accession, null)).withRel(%22curationLink%22);%0A    %7D
 %0A    %0A    public
@@ -3363,24 +3363,90 @@
 ession()));%0A
+%09%09sampleResource.add(getCurationLinkLink(sample.getAccession()));%0A
 %09%09return sam
@@ -3539,48 +3539,25 @@
 %7B%0A%09%09
-Resource%3CSample%3E resource = new 
+return to
 Resource
 %3C%3E(s
@@ -3556,587 +3556,55 @@
 urce
-%3C%3E
 (sample
-);%0A%09%09%0A%09%09resource.add(ControllerLinkBuilder.linkTo(SampleRestController.class, sample.getAccession()).withSelfRel());%0A%09%09%09%09%09%09%09%0A%09%09resource.add(ControllerLinkBuilder.linkTo(%0A%09%09%09%09ControllerLinkBuilder.methodOn(SampleCurationLinksRestController.class)%0A%09%09%09%09%09.getCurationLinkPageJson(sample.getAccession(), null, null)).withRel(%22curationLinks%22));%0A%09%09resource.add(ControllerLinkBuilder.linkTo(%0A%09%09%09%09ControllerLinkBuilder.methodOn(SampleCurationLinksRestController.class)%0A%09%09%09%09%09.getCurationLinkJson(sample.getAccession(), null)).withRel(%22curationLink%22));%0A%09%09%0A%09%09return resource;%0A%09%7D%0A    
+, Optional.empty(), Optional.empty());%0A%09%7D
 %0A%0A%7D

fix curationLink rel generation