package com.infoclinika.pdx.controller;

import com.infoclinika.pdx.service.FileParser;
import com.infoclinika.pdx.service.ParsedFile;
import com.infoclinika.pdx.service.ProcessedFile;
import com.infoclinika.pdx.service.exception.ApplicationException;
import com.infoclinika.pdx.service.experiment.PathwayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * Handles requests to upload pathway data.
 */
@RestController
@RequestMapping("/api/upload")
public class PathwayUploadController {
    private static final String FILE_PARAM = "file";
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final FileParser fileParser;
    private final PathwayService pathwayService;

    /**
     * Constructor to provide required services.
     */
    @Autowired
    public PathwayUploadController(FileParser fileParser, PathwayService pathwayService) {
        this.fileParser = fileParser;
        this.pathwayService = pathwayService;
    }

    /**
     * Handles upload of pathway data file.
     *
     * @param file file to parse
     */
    @PostMapping("/pathway")
    @ResponseStatus(HttpStatus.OK)
    public void uploadFile(@RequestParam(FILE_PARAM) MultipartFile file) throws ApplicationException {
        logger.debug("Request to /api/upload/pathway");

        final ParsedFile parsedFile = fileParser.parseFile(file);
        pathwayService.save(parsedFile);
    }

    /**
     * Handles upload of large pathway data file.
     *
     * @param file file to parse
     */
    @PostMapping("/pathway/batch")
    @ResponseStatus(HttpStatus.OK)
    public void uploadLargeFile(@RequestParam(FILE_PARAM) MultipartFile file) throws ApplicationException {
        logger.debug("Request to /api/upload/pathway/batch");

        final ProcessedFile processedFile = fileParser.parseChunks(file);
        pathwayService.save(processedFile);
    }

    /**
     * Handles upload of pathway types.
     *
     * @param file file to parse
     */
    @PostMapping("/pathway/type")
    @ResponseStatus(HttpStatus.OK)
    public void addPathwayTypes(@RequestParam(FILE_PARAM) MultipartFile file) {
        logger.debug("Request to /api/upload/pathway");

        final ParsedFile parsedFile = fileParser.parseFile(file);
        pathwayService.setPathwayTypes(parsedFile);
    }

    /**
     * Handles upload of genes content associated with pathways.
     *
     * @param file file to parse
     */
    @PostMapping("/pathway/genes")
    @ResponseStatus(HttpStatus.OK)
    public void addAssociatedGenes(@RequestParam(FILE_PARAM) MultipartFile file) throws ApplicationException {
        logger.debug("Request to /api/upload/pathway/genes");

        final ParsedFile parsedFile = fileParser.parseFileWithoutShift(file);
        pathwayService.setGeneContent(parsedFile);
    }
}
