package eu.dnetlib.repo.manager.controllers;

import eu.dnetlib.repo.manager.service.BrokerServiceImpl;
import eu.dnetlib.repo.manager.shared.BrokerException;
import eu.dnetlib.repo.manager.shared.Term;
import eu.dnetlib.repo.manager.shared.broker.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiParam;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/broker")
@Api(description = "Broker API",  tags = {"broker"})
public class BrokerController{

    @Autowired
    BrokerServiceImpl brokerService;


    @RequestMapping(value = "/getDatasourcesOfUser" , method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER')")
    DatasourcesBroker getDatasourcesOfUser(@RequestParam("user")
                                           @ApiParam(value = "User email", required = true) String user,
                                           @RequestParam("includeShared")
                                           @ApiParam(value = "Include shared datasources", required = true , defaultValue = "false") String includeShared,
                                           @RequestParam("includeByOthers")
                                           @ApiParam(value = "Include datasources of other", required = true,defaultValue = "false") String includeByOthers) throws JSONException {
        return brokerService.getDatasourcesOfUser(user, includeShared, includeByOthers);
    }

    @RequestMapping(value = "/getTopicsForDatasource/{datasourceName:.+}" ,
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    List<BrowseEntry> getTopicsForDatasource(@PathVariable("datasourceName")  String datasourceName) throws BrokerException{
        return brokerService.getTopicsForDatasource(datasourceName);
    }

    @RequestMapping(value = "/advancedShowEvents/{page}/{size}" ,
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER')")
    EventsPage advancedShowEvents(@PathVariable("page") String page,
                                  @PathVariable("size") String size,
                                  @RequestBody AdvQueryObject advQueryObject) throws BrokerException, JSONException ,IOException{
        return brokerService.advancedShowEvents(page, size, advQueryObject);
    }

    @RequestMapping(value = "/showEvents/{datasourceName:.+}/{topic}/{page}" ,
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER')")
    EventsPage showEvents(@RequestParam("datasourceName") String datasourceName,
                          @RequestParam("topic") String topic,
                          @RequestParam("page") String page,
                          @RequestParam("size") String size) throws BrokerException, JSONException{
        return brokerService.showEvents(datasourceName, topic, page, size);
    }

    @RequestMapping(value = "/getSimpleSubscriptionsOfUser/{userEmail}" ,
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER')")
    Map<String, List<SimpleSubscriptionDesc>> getSimpleSubscriptionsOfUser(@PathVariable("userEmail")  String userEmail) throws BrokerException{
        return brokerService.getSimpleSubscriptionsOfUser(userEmail);
    }

    @RequestMapping(value = "/subscribe" , method = RequestMethod.POST,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER') ")
    Subscription subscribe(@RequestBody OpenaireSubscription obj) throws BrokerException{
        return brokerService.subscribe(obj);
    }

    @RequestMapping(value = "/unsubscribe/{subscriptionId}" , method = RequestMethod.POST,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER')")
    ResponseEntity<Object> unsubscribe(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException{
        return brokerService.unsubscribe(subscriptionId);
    }

    @RequestMapping(value = "/getSubscription/{subscriptionId}" , method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER')")
    Subscription getSubscription(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException{
        return brokerService.getSubscription(subscriptionId);
    }


    @RequestMapping(value = "/getDnetTopics" , method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    Map<String, Term> getDnetTopics() throws BrokerException{
        return brokerService.getDnetTopics();
    }

    @RequestMapping(value = "/getNotificationsBySubscriptionId/{subscriptionId}/{page}/{size}" , method = RequestMethod.GET
            ,produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @PreAuthorize("hasRole('ROLE_USER')")
    EventsPage getNotificationsBySubscriptionId(@PathVariable("subscriptionId") String subscriptionId,
                                                @PathVariable("page") String page,
                                                @PathVariable("size") String size) throws BrokerException{
        return brokerService.getNotificationsBySubscriptionId(subscriptionId, page, size);
    }

    /*@RequestMapping(value = "/getSubscriptionsOfUser/{userEmail}" , method = RequestMethod.GET
            ,produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody*/
    Map<String, List<Subscription>> getSubscriptionsOfUser(String userEmail) throws BrokerException{
        return brokerService.getSubscriptionsOfUser(userEmail);
    }


}
