package com.qmth.boot.api.controller;

import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.core.exception.ParameterException;
import com.qmth.boot.core.fss.service.FileStoreService;
import com.qmth.boot.core.fss.store.FileStore;
import com.qmth.boot.core.fss.utils.FssUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;

@CrossOrigin
@RestController
@RequestMapping(FssUtils.INNER_ENDPOINT_PREFIX)
@Aac(auth = false, strict = false)
public class FssController {

    @Resource
    private FileStoreService fileStoreService;

    @GetMapping("/**")
    public ResponseEntity<InputStreamResource> get(HttpServletRequest request,
            @RequestParam(name = FssUtils.INNER_ENDPOINT_PARAM_BUCKET) @NotBlank String bucket,
            @RequestParam(name = FssUtils.INNER_ENDPOINT_PARAM_EXPIRE_TIME) @Min(0) Long expireTime,
            @RequestParam(name = FssUtils.INNER_ENDPOINT_PARAM_SIGNATURE) @NotBlank String signature) throws Exception {
        String path = request.getServletPath().substring(FssUtils.INNER_ENDPOINT_PREFIX.length() + 1);
        FileStore fileStore = fileStoreService.getFileStore(bucket);
        if (fileStore == null) {
            throw new ParameterException("bucket not exists: " + bucket);
        }
        if (expireTime <= 0) {
            throw new ParameterException("expireTime is invalid");
        }
        return ResponseEntity.ok()
                .contentType(MediaTypeFactory.getMediaType(path).orElse(MediaType.APPLICATION_OCTET_STREAM))
                .body(new InputStreamResource(
                        fileStore.readServerUrl(bucket, path, expireTime, StringUtils.trimToEmpty(signature))));
    }

}
