package com.infoclinika.pdx.controller;

import com.infoclinika.pdx.domain.sample.SampleType;
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.mutation.MutationService;
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 Mutation data.
 */
@RestController
@RequestMapping("/api/upload")
public class MutationUploadController {
    private static final String FILE_PARAM = "file";
    private static final String FORMAT_PARAM = "format";
    private static final String TYPE_PARAM = "type";

    private static final String CSV = "CSV";
    private static final String TSV = "TSV";

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final FileParser fileParser;
    private final MutationService mutationService;


    /**
     * Constructor to provide required services.
     */
    @Autowired
    public MutationUploadController(FileParser fileParser, MutationService service) {
        this.fileParser = fileParser;
        this.mutationService = service;
    }

    /**
     * Handles upload of Mutation data.
     *
     * @param file file to parse
     */
    @PostMapping("/mutation")
    @ResponseStatus(HttpStatus.OK)
    public void postFile(@RequestParam(FILE_PARAM) MultipartFile file,
                         @RequestParam(TYPE_PARAM) SampleType type,
                         @RequestParam(name = FORMAT_PARAM, required = false, defaultValue = TSV) String format)
            throws ApplicationException {
        logger.debug("Request to /upload/mutation");

        final ParsedFile parsedFile = format.equals(CSV)
                                      ? fileParser.parseCsvFile(file)
                                      : fileParser.parseFile(file);
        mutationService.save(parsedFile, type);
    }

    /**
     * Handles upload of large Mutation data.
     *
     * @param file file to parse
     */
    @PostMapping("/mutation/batch")
    @ResponseStatus(HttpStatus.OK)
    public void postLargeFile(@RequestParam(FILE_PARAM) MultipartFile file,
                              @RequestParam(TYPE_PARAM) SampleType type,
                              @RequestParam(name = FORMAT_PARAM, required = false, defaultValue = TSV) String format)
            throws ApplicationException {
        logger.debug("Request to /upload/mutation/batch");

        final ProcessedFile processedFile = format.equals(CSV)
                                            ? fileParser.parseCsvChunks(file)
                                            : fileParser.parseChunks(file);
        mutationService.save(processedFile, type);
    }
}
