/*
 * Copyright 2020 B2i Healthcare Pte Ltd, http://b2i.sg
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.b2international.snowowl.snomed.core.rest;

import java.io.File;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.b2international.snowowl.core.ApplicationContext;
import com.b2international.snowowl.core.attachments.AttachmentRegistry;
import com.b2international.snowowl.core.attachments.InternalAttachmentRegistry;
import com.b2international.snowowl.core.date.DateFormats;
import com.b2international.snowowl.core.date.Dates;
import com.b2international.snowowl.core.domain.ExportResult;
import com.b2international.snowowl.core.rest.AbstractRestService;
import com.b2international.snowowl.snomed.core.domain.Rf2RefSetExportLayout;
import com.b2international.snowowl.snomed.core.rest.domain.SnomedRf2ExportConfiguration;
import com.b2international.snowowl.snomed.datastore.config.SnomedCoreConfiguration;
import com.b2international.snowowl.snomed.datastore.request.SnomedRequests;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

/**
 * @since 7.5
 */
@Api(value = "Export", description="Export", tags = "export")
@Controller
@RequestMapping(value="/{path:**}/export")
public class SnomedRf2ExportRestService extends AbstractSnomedRestService {

	@Autowired
	private AttachmentRegistry attachments;
	
	@ApiOperation(
		value="Export SNOMED CT content to RF2", 
		notes="Exports SNOMED CT content from the given branch to RF2."
	)
	@ApiResponses({
		@ApiResponse(code=200, message="OK")
	})
	@GetMapping(produces = { AbstractRestService.OCTET_STREAM_MEDIA_TYPE })
	public @ResponseBody ResponseEntity<Resource> export(
			@ApiParam(value = "The branch path", required = true)
			@PathVariable(value="path")
			final String branch,

			final SnomedRf2ExportConfiguration params,
			
			@ApiParam(value = "Accepted language tags, in order of preference")
			@RequestHeader(value=HttpHeaders.ACCEPT_LANGUAGE, defaultValue="en-US;q=0.8,en-GB;q=0.6", required=false) 
			final String acceptLanguage) {
		
		final Rf2RefSetExportLayout globalExportLayout = ApplicationContext.getServiceForClass(SnomedCoreConfiguration.class).getExport().getRefSetExportLayout();
		
		final ExportResult exportedFile = SnomedRequests.rf2().prepareExport()
			.setReleaseType(params.getType())
			.setExtensionOnly(params.isExtensionOnly())
			.setLocales(acceptLanguage)
			.setIncludePreReleaseContent(params.isIncludeUnpublished())
			.setModules(params.getModuleIds())
			.setRefSets(params.getRefSetIds())
			.setCountryNamespaceElement(params.getNamespaceId())
			// .setNamespaceFilter(namespaceFilter) is not supported on REST, yet
			.setTransientEffectiveTime(params.getTransientEffectiveTime())
			.setStartEffectiveTime(params.getStartEffectiveTime())
			.setEndEffectiveTime(params.getEndEffectiveTime())
			.setRefSetExportLayout(params.getRefSetLayout() == null ? globalExportLayout : params.getRefSetLayout())
			.setReferenceBranch(branch)
			.build(this.repositoryId)
			.execute(getBus())
			.getSync();
		
		final File file = ((InternalAttachmentRegistry) attachments).getAttachment(exportedFile.getRegistryId());
		final Resource exportZipResource = new FileSystemResource(file);
		
		final HttpHeaders httpHeaders = new HttpHeaders();
		
		httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		httpHeaders.set("Content-Disposition", "attachment; filename=\"snomed_export_" + Dates.formatByHostTimeZone(new Date(), DateFormats.COMPACT_LONG) + ".zip\"");

		file.deleteOnExit();
		return new ResponseEntity<>(exportZipResource, httpHeaders, HttpStatus.OK);
	}
	
}

@@ -695,31 +695,8 @@
 ile;
-%0Aimport java.util.Date;
 %0A%0Aim
@@ -1650,202 +1650,26 @@
 re.d
-ate.DateFormats;%0Aimport com.b2international.snowowl.core.date.Dates;%0Aimport com.b2international.snowowl.core.domain.ExportResult;%0Aimport com.b2international.snowowl.core.rest.AbstractRestService
+omain.ExportResult
 ;%0Aim
@@ -2676,68 +2676,8 @@
 ping
-(produces = %7B AbstractRestService.OCTET_STREAM_MEDIA_TYPE %7D)
 %0A%09pu
@@ -2710,24 +2710,17 @@
 eEntity%3C
-Resource
+?
 %3E export
@@ -4425,18 +4425,15 @@
 .set
-(%22
 Content
--
 Disp
@@ -4439,19 +4439,25 @@
 position
-%22, 
+FormData(
 %22attachm
@@ -4463,117 +4463,155 @@
 ment
-; filename=%5C%22snomed_export_%22 + Dates.formatByHostTimeZone(new Date(), DateFormats.COMPACT_LONG) + %22.zip%5C%22%22);%0A
+%22, exportedFile.getName());%0A%0A%09%09// TODO figure out a smart way to cache export results, probably it could be tied to commitTimestamps/versions/etc. 
 %0A%09%09f

remove produces part from export endpoint