package de.retest.recheck.persistence;

import static de.retest.recheck.XmlTransformerUtil.getXmlTransformer;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Paths;

import de.retest.recheck.Properties;
import de.retest.recheck.auth.RetestAuthentication;
import de.retest.recheck.persistence.bin.KryoPersistence;
import de.retest.recheck.persistence.xml.XmlFolderPersistence;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CloudPersistence<T extends Persistable> implements Persistence<T> {
	private static final String SERVICE_ENDPOINT = "https://marvin.prod.cloud.retest.org/api/report";
	private final KryoPersistence<T> kryoPersistence = new KryoPersistence<>();
	private final XmlFolderPersistence<T> folderPersistence = new XmlFolderPersistence<>( getXmlTransformer() );

	public static final String RECHECK_API_KEY = "RECHECK_API_KEY";

	@Override
	public void save( final URI identifier, final T element ) throws IOException {
		kryoPersistence.save( identifier, element );
		if ( identifier.getPath().endsWith( Properties.AGGREGATED_TEST_REPORT_FILE_NAME ) ) {
			saveToCloud( identifier );
		}
	}

	private void saveToCloud( final URI identifier ) throws IOException {
		final HttpResponse<String> uploadUrlResponse = getUploadUrl();

		if ( uploadUrlResponse.isSuccess() ) {
			uploadReport( identifier, uploadUrlResponse.getBody() );
		}
	}

	private void uploadReport( final URI identifier, final String url ) throws IOException {
		final HttpResponse<?> uploadResponse = Unirest.put( url ) //
				.header( "x-amz-meta-report-name", Paths.get( identifier ).getFileName().toString() )
				.field( "upload", new File( identifier ) ) //
				.asEmpty();

		if ( uploadResponse.isSuccess() ) {
			log.info( "Successfully uploaded report to rehub" );
		}
	}

	private HttpResponse<String> getUploadUrl() {
		final RetestAuthentication auth = RetestAuthentication.getInstance();
		final String token = String.format( "Bearer %s", auth.getAccessTokenString() );

		return Unirest.post( SERVICE_ENDPOINT ) //
				.header( "Authorization", token )//
				.asString();
	}

	@Override
	public T load( final URI identifier ) throws IOException {
		if ( Paths.get( identifier ).toFile().isDirectory() ) {
			return folderPersistence.load( identifier );
		}
		return kryoPersistence.load( identifier );
	}

}

@@ -201,16 +201,75 @@
 e.Paths;
+%0Aimport java.util.List;%0Aimport java.util.stream.Collectors;
 %0A%0Aimport
@@ -468,24 +468,119 @@
 ersistence;%0A
+import de.retest.recheck.report.SuiteReplayResult;%0Aimport de.retest.recheck.report.TestReport;%0A
 import kong.
@@ -1248,16 +1248,17 @@
  );%0A
+%0A
 %09%09if ( i
 dent
@@ -1257,121 +1257,487 @@
  ( i
-dentifier.getPath().endsWith( Properties.AGGREGATED_TEST_REPORT_FILE_NAME ) ) %7B%0A%09%09%09saveToCloud( identifier );%0A%09%09%7D
+sAggregatedReport( identifier ) && element instanceof TestReport ) %7B%0A%09%09%09saveToCloud( identifier, (TestReport) element );%0A%09%09%7D%0A%09%7D%0A%0A%09private boolean isAggregatedReport( final URI identifier ) %7B%0A%09%09return identifier.getPath().endsWith( Properties.AGGREGATED_TEST_REPORT_FILE_NAME );%0A%09%09%7D%0A%0A%09private List%3CString%3E getTestClasses( final TestReport report ) %7B%0A%09%09return report.getSuiteReplayResults().stream() //%0A%09%09%09%09.map( SuiteReplayResult::getName ) //%0A%09%09%09%09.collect( Collectors.toList() );
 %0A%09%7D%0A
@@ -1776,32 +1776,57 @@
 l URI identifier
+, final TestReport report
  ) throws IOExce
@@ -1897,27 +1897,141 @@
 adUrl();%0A%0A%09%09
-if 
+final ReportUploadMetadata metadata = ReportUploadMetadata.builder() //%0A%09%09%09%09.location( identifier ) //%0A%09%09%09%09.uploadUrl
 ( uploadUrlR
@@ -2042,181 +2042,369 @@
 nse.
-isSuccess
+getBody
 () ) 
-%7B
+//
 %0A%09%09%09
-uploadReport( identifier, uploadUrlResponse.getBody() );%0A%09%09%7D%0A%09%7D%0A%0A%09private void uploadReport( final URI identifier, final String url ) throws IOException %7B
+%09.testClasses( getTestClasses( report ) ) //%0A%09%09%09%09.build();%0A%0A%09%09if ( uploadUrlResponse.isSuccess() ) %7B%0A%09%09%09uploadReport( metadata );%0A%09%09%7D%0A%09%7D%0A%0A%09private void uploadReport( final ReportUploadMetadata metadata ) throws IOException %7B%0A%09%09final String reportName = metadata.getTestClasses() //%0A%09%09%09%09.stream() //%0A%09%09%09%09.collect( Collectors.joining( %22, %22 ) );%0A
 %0A%09%09f
@@ -2458,11 +2458,31 @@
 ut( 
-url
+metadata.getUploadUrl()
  ) /
@@ -2526,58 +2526,23 @@
 e%22, 
-Paths.get( identifier ).getFileName().toString() )
+reportName ) //
 %0A%09%09%09
@@ -2570,26 +2570,38 @@
 w File( 
-identifier
+metadata.getLocation()
  ) ) //%0A

Use test class(es) as report name