package uk.ac.ebi.biosamples.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;

import uk.ac.ebi.biosamples.MessageContent;
import uk.ac.ebi.biosamples.Messaging;
import uk.ac.ebi.biosamples.model.CurationLink;
import uk.ac.ebi.biosamples.model.Relationship;
import uk.ac.ebi.biosamples.model.Sample;

@Service
public class MessagingService {

	private final SampleReadService sampleReadService;
	private final AmqpTemplate amqpTemplate;
	
	public MessagingService(SampleReadService sampleReadService, AmqpTemplate amqpTemplate) {
		this.sampleReadService = sampleReadService;
		this.amqpTemplate = amqpTemplate;
	}
	
	public void sendMessages(CurationLink curationLink) {
		Optional<Sample> target = sampleReadService.fetch(curationLink.getSample());
		if (target.isPresent()) {
			sendMessages(target.get());
		}
	}
	

	public void sendMessages(Sample sample) {
		
		//for each sample we have a relationship to, update it to index this sample as an inverse relationship	
		List<Sample> related = new ArrayList<>();
		for (Relationship relationship : sample.getRelationships()) {
			if (relationship.getSource() != null && relationship.getSource().equals(sample.getAccession())) {
				Optional<Sample> target = sampleReadService.fetch(relationship.getTarget());
				if (target.isPresent()) {
					related.add(target.get());
				}
			}
		}	
		
		//send the original sample with the extras as related samples
		amqpTemplate.convertAndSend(Messaging.exchangeForIndexingSolr, "", 
				MessageContent.build(sample, null, related, false));
		
	}
	
	public List<Sample> getDerivedFromSamples(Sample sample, List<Sample> related) {
		
		for (Relationship relationship : sample.getRelationships()) {
			if (relationship.getSource().equals(sample.getAccession())) {
				if (relationship.getType().toLowerCase().equals("derived from")) {
					Optional<Sample> target = sampleReadService.fetch(relationship.getTarget());
					if (target.isPresent()) {
						if (!related.contains(target.get())) {
							related.add(target.get());
							getDerivedFromSamples(target.get(), related);
						}
					}
				}
			}
		}
		return related;
	}
	
}

@@ -795,244 +795,344 @@
 oid 
-sendMessages(CurationLink curationLink) %7B%0A%09%09Optional%3CSample%3E target = sampleReadService.fetch(curationLink.getSample());%0A%09%09if (target.isPresent()) %7B%0A%09%09%09sendMessages(target.get()
+fetchThenSendMessage(String accession) %7B%0A%09%09if (accession == null) throw new IllegalArgumentException(%22accession cannot be null%22);%0A%09%09if (accession.trim().length() == 0) throw new IllegalArgumentException(%22accession cannot be empty%22
 );%0A%09%09
-%7D
 %0A%09
-%7D%0A%09%0A%0A%09public void sendMessages(Sample sample
+%09%0A%09%09Optional%3CSample%3E sample = sampleReadService.fetch(accession);%0A%09%09if (sample.isPresent()
 ) %7B%0A%09%09
-%0A
+%09%0A%09
 %09%09//
@@ -1233,16 +1233,41 @@
 onship%09%0A
+%09%09%09//TODO do this async%0A%09
 %09%09List%3CS
@@ -1304,16 +1304,17 @@
 %3C%3E();%0A%09%09
+%09
 for (Rel
@@ -1337,32 +1337,38 @@
 onship : sample.
+get().
 getRelationships
@@ -1365,32 +1365,33 @@
 ationships()) %7B%0A
+%09
 %09%09%09if (relations
@@ -1414,16 +1414,23 @@
 != null 
+%0A%09%09%09%09%09%09
 && relat
@@ -1456,35 +1456,25 @@
 .equals(
-sample.getA
+a
 ccession
 ())) %7B%0A%09
@@ -1461,31 +1461,30 @@
 ls(accession
-()
 )) %7B%0A
+%09
 %09%09%09%09Optional
@@ -1552,24 +1552,25 @@
 get());%0A%09%09%09%09
+%09
 if (target.i
@@ -1579,24 +1579,25 @@
 resent()) %7B%0A
+%09
 %09%09%09%09%09related
@@ -1624,23 +1624,28 @@
 %09%09%09%09
+%09
 %7D%0A
+%09
 %09%09%09%7D%0A
+%09
 %09%09%7D%09%0A%09%09
-%0A
+%09%0A%09
 %09%09//
@@ -1706,16 +1706,17 @@
 mples%0A%09%09
+%09
 amqpTemp
@@ -1779,16 +1779,17 @@
 %22, %0A%09%09%09%09
+%09
 MessageC
@@ -1807,16 +1807,22 @@
 d(sample
+.get()
 , null, 
@@ -1841,16 +1841,252 @@
 se));%0A%09%09
+%7D%0A%09%09%0A%09%7D%0A%09%0A%09@Deprecated%0A%09public void sendMessages(CurationLink curationLink) %7B%0A%09%09fetchThenSendMessage(curationLink.getSample());%0A%09%7D%0A%09%0A%0A%09@Deprecated%0A%09public void sendMessages(Sample sample) %7B%0A%09%09fetchThenSendMessage(sample.getAccession());
 %0A%09%7D%0A%09%0A%09p

fix handling of curation for indexing GSB-1086