package de.techdev.trackr.core.web.api;

import de.techdev.trackr.core.web.converters.DateConverter;
import de.techdev.trackr.domain.ApiBeansConfiguration;
import de.techdev.trackr.domain.company.*;
import de.techdev.trackr.domain.employee.Employee;
import de.techdev.trackr.domain.employee.EmployeeEventHandler;
import de.techdev.trackr.domain.employee.login.Authority;
import de.techdev.trackr.domain.employee.login.Credential;
import de.techdev.trackr.domain.employee.login.CredentialEventHandler;
import de.techdev.trackr.domain.employee.vacation.VacationRequest;
import de.techdev.trackr.domain.employee.vacation.VacationRequestEventHandler;
import de.techdev.trackr.domain.project.*;
import org.springframework.context.annotation.*;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.format.FormatterRegistry;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import java.util.List;

/**
 * @author Moritz Schulze
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "de.techdev.trackr",
        useDefaultFilters = false,
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class, ControllerAdvice.class})
        })
@Import({ApiBeansConfiguration.class})
public class ApiWebMvcConfiguration extends RepositoryRestMvcConfiguration {

    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(new Class[]{Employee.class, Credential.class, Authority.class, Company.class, ContactPerson.class,
                Address.class, Project.class, WorkTime.class, BillableTime.class, VacationRequest.class});
        config.setReturnBodyOnUpdate(true);
        config.setReturnBodyOnCreate(true);
    }

    @Bean
    public VacationRequestEventHandler vacationRequestEventHandler() {
        return new VacationRequestEventHandler();
    }

    @Bean
    public BillableTimeEventHandler billableTimeEventHandler() {
        return new BillableTimeEventHandler();
    }

    @Bean
    public WorkTimeEventHandler workTimeEventHandler() {
        return new WorkTimeEventHandler();
    }

    @Bean
    public ProjectEventHandler projectEventHandler() {
        return new ProjectEventHandler();
    }

    @Bean
    public EmployeeEventHandler employeeEventHandler() {
        return new EmployeeEventHandler();
    }

    @Bean
    public AddressEventHandler addressEventHandler() {
        return new AddressEventHandler();
    }

    @Bean
    public ContactPersonEventHandler contactPersonEventHandler() {
        return new ContactPersonEventHandler();
    }

    @Bean
    public CompanyEventHandler companyEventHandler() {
        return new CompanyEventHandler();
    }

    @Bean
    public CredentialEventHandler credentialEventHandler() {
        return new CredentialEventHandler();
    }

    @Bean
    public DateConverter dateConverter() {
        return new DateConverter();
    }

    @Override
    protected void configureConversionService(ConfigurableConversionService conversionService) {
        super.configureConversionService(conversionService);
        conversionService.addConverter(dateConverter());
    }

    /**
     * Somehow the "normal" Spring MVC (not spring-data-rest) does not use the converter registered in {@link #configureConversionService} so we have to register it again.
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(dateConverter());
    }

    @Bean
    public JsonMappingHandlerExceptionResolver jsonMappingHandlerExceptionResolver() {
        return new JsonMappingHandlerExceptionResolver();
    }

    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
        exceptionResolvers.add(jsonMappingHandlerExceptionResolver());
        super.configureHandlerExceptionResolvers(exceptionResolvers);
    }
}
@@ -189,17 +189,23 @@
 company.
-*
+Address
 ;%0Aimport
@@ -230,33 +230,31 @@
 .domain.
-employee.Employee
+company.Company
 ;%0Aimport
@@ -271,32 +271,87 @@
 v.trackr.domain.
+company.ContactPerson;%0Aimport de.techdev.trackr.domain.
 employee.Employe
@@ -351,28 +351,16 @@
 Employee
-EventHandler
 ;%0Aimport
@@ -474,79 +474,8 @@
 al;%0A
-import de.techdev.trackr.domain.employee.login.CredentialEventHandler;%0A
 impo
@@ -573,53 +573,77 @@
 ain.
-employee.vacation.VacationRequestEventHandler
+project.BillableTime;%0Aimport de.techdev.trackr.domain.project.Project
 ;%0Aim
@@ -680,17 +680,24 @@
 project.
-*
+WorkTime
 ;%0Aimport
@@ -814,24 +814,101 @@
 ionService;%0A
+import org.springframework.data.rest.core.annotation.RepositoryEventHandler;%0A
 import org.s
@@ -1496,16 +1496,23 @@
 v.trackr
+.domain
 %22,%0A     
@@ -1685,16 +1685,46 @@
 ce.class
+, RepositoryEventHandler.class
 %7D)%0A     
@@ -2308,1074 +2308,84 @@
 lic 
-VacationRequestEventHandler vacationRequestEventHandler() %7B%0A        return new VacationRequestEventHandler();%0A    %7D%0A%0A    @Bean%0A    public BillableTimeEventHandler billableTimeEventHandler() %7B%0A        return new BillableTimeEventHandler();%0A    %7D%0A%0A    @Bean%0A    public WorkTimeEventHandler workTimeEventHandler() %7B%0A        return new WorkTimeEventHandler();%0A    %7D%0A%0A    @Bean%0A    public ProjectEventHandler projectEventHandler() %7B%0A        return new ProjectEventHandler();%0A    %7D%0A%0A    @Bean%0A    public EmployeeEventHandler employeeEventHandler() %7B%0A        return new EmployeeEventHandler();%0A    %7D%0A%0A    @Bean%0A    public AddressEventHandler addressEventHandler() %7B%0A        return new AddressEventHandler();%0A    %7D%0A%0A    @Bean%0A    public ContactPersonEventHandler contactPersonEventHandler() %7B%0A        return new ContactPersonEventHandler();%0A    %7D%0A%0A    @Bean%0A    public CompanyEventHandler companyEventHandler() %7B%0A        return new CompanyEventHandler();%0A    %7D%0A%0A    @Bean%0A    public CredentialEventHandler credentialEventHandler() %7B%0A        return new CredentialEventHandler
+ExceptionHandlers exceptionHandlers() %7B%0A        return new ExceptionHandlers
 ();%0A

Load @RepositoryEventHandlers via @ComponentScan