/*
 * Copyright 2019 EPAM Systems
 *
 * 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.epam.ta.reportportal.ws.controller;

import com.epam.ta.reportportal.commons.EntityUtils;
import com.epam.ta.reportportal.commons.ReportPortalUser;
import com.epam.ta.reportportal.core.file.GetFileHandler;
import com.epam.ta.reportportal.core.user.EditUserHandler;
import com.epam.ta.reportportal.entity.attachment.BinaryData;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.ws.model.OperationCompletionRS;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;
import static com.epam.ta.reportportal.auth.permissions.Permissions.ASSIGNED_TO_PROJECT;
import static com.epam.ta.reportportal.util.ProjectExtractor.extractProjectDetails;

/**
 * @author Dzianis_Shybeka
 */
@RestController
@RequestMapping("/v1/data")
public class FileStorageController {

	private final EditUserHandler editUserHandler;

	private final GetFileHandler getFileHandler;

	@Autowired
	public FileStorageController(EditUserHandler editUserHandler, GetFileHandler getFileHandler) {
		this.editUserHandler = editUserHandler;
		this.getFileHandler = getFileHandler;
	}

	@Transactional(readOnly = true)
	@PreAuthorize(ASSIGNED_TO_PROJECT)
	@GetMapping(value = "/{projectName}/{dataId}")
	public void getFile(@PathVariable String projectName, @PathVariable("dataId") String dataId, HttpServletResponse response,
			@AuthenticationPrincipal ReportPortalUser user) {
		toResponse(response, getFileHandler.loadFileById(dataId, extractProjectDetails(user, projectName)));
	}

	/**
	 * (non-Javadoc)
	 */
	@Transactional(readOnly = true)
	@GetMapping(value = "/photo")
	@ApiOperation("Get photo of current user")
	public void getMyPhoto(@AuthenticationPrincipal ReportPortalUser user, HttpServletResponse response,
			@RequestParam(value = "loadThumbnail", required = false) boolean loadThumbnail) {
		toResponse(response, getFileHandler.getUserPhoto(user, loadThumbnail));
	}

	/**
	 * (non-Javadoc)
	 */
	@Transactional(readOnly = true)
	@PreAuthorize(ASSIGNED_TO_PROJECT)
	@GetMapping(value = "/{projectName}/userphoto")
	@ApiOperation("Get user's photo")
	public void getUserPhoto(@PathVariable String projectName, @RequestParam(value = "id") String username,
			@RequestParam(value = "loadThumbnail", required = false) boolean loadThumbnail, HttpServletResponse response,
			@AuthenticationPrincipal ReportPortalUser user) {
		BinaryData userPhoto = getFileHandler.getUserPhoto(EntityUtils.normalizeId(username),
				user,
				extractProjectDetails(user, projectName),
				loadThumbnail
		);
		toResponse(response, userPhoto);
	}

	@Transactional
	@PreAuthorize(ADMIN_ONLY)
	@GetMapping("/userphoto")
	@ApiIgnore
	public void getUserPhotoByAdmin(@RequestParam(value = "id") String username,
			@RequestParam(value = "loadThumbnail", required = false) boolean loadThumbnail, HttpServletResponse response,
			@AuthenticationPrincipal ReportPortalUser user) {
		BinaryData userPhoto = getFileHandler.getUserPhoto(EntityUtils.normalizeId(username), user, null, loadThumbnail);
		toResponse(response, userPhoto);
	}

	@Transactional
	@PostMapping(value = "/photo", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
	@ApiOperation("Upload user's photo")
	public OperationCompletionRS uploadPhoto(@RequestParam("file") MultipartFile file, @AuthenticationPrincipal ReportPortalUser user) {
		return editUserHandler.uploadPhoto(EntityUtils.normalizeId(user.getUsername()), file);
	}

	@Transactional
	@DeleteMapping(value = "/photo")
	@ApiOperation("Delete user's photo")
	public OperationCompletionRS deletePhoto(@AuthenticationPrincipal ReportPortalUser user) {
		return editUserHandler.deletePhoto(EntityUtils.normalizeId(user.getUsername()));
	}

	/**
	 * Copies data from provided {@link InputStream} to Response
	 *
	 * @param response   Response
	 * @param binaryData Stored data
	 */
	private void toResponse(HttpServletResponse response, BinaryData binaryData) {
		if (binaryData.getInputStream() != null) {
			try {
				response.setContentType(binaryData.getContentType());
				IOUtils.copy(binaryData.getInputStream(), response.getOutputStream());
			} catch (IOException e) {
				throw new ReportPortalException("Unable to retrieve binary data from data storage", e);
			}
		} else {
			response.setStatus(HttpStatus.NO_CONTENT.value());
		}
	}
}

@@ -1602,62 +1602,8 @@
 ile;
-%0Aimport springfox.documentation.annotations.ApiIgnore;
 %0A%0Aim
@@ -1708,88 +1708,8 @@
 m;%0A%0A
-import static com.epam.ta.reportportal.auth.permissions.Permissions.ADMIN_ONLY;%0A
 impo
@@ -3749,489 +3749,8 @@
 %09%7D%0A%0A
-%09@Transactional%0A%09@PreAuthorize(ADMIN_ONLY)%0A%09@GetMapping(%22/userphoto%22)%0A%09@ApiIgnore%0A%09public void getUserPhotoByAdmin(@RequestParam(value = %22id%22) String username,%0A%09%09%09@RequestParam(value = %22loadThumbnail%22, required = false) boolean loadThumbnail, HttpServletResponse response,%0A%09%09%09@AuthenticationPrincipal ReportPortalUser user) %7B%0A%09%09BinaryData userPhoto = getFileHandler.getUserPhoto(EntityUtils.normalizeId(username), user, null, loadThumbnail);%0A%09%09toResponse(response, userPhoto);%0A%09%7D%0A%0A
 %09@Tr

remove get user photo endpoint for admin