package uk.ac.ebi.quickgo.ontology;

import uk.ac.ebi.quickgo.ontology.controller.validation.OBOControllerValidationHelper;
import uk.ac.ebi.quickgo.ontology.controller.validation.OBOControllerValidationHelperImpl;
import uk.ac.ebi.quickgo.rest.period.Period;
import uk.ac.ebi.quickgo.rest.period.RemainingTimeSupplier;
import uk.ac.ebi.quickgo.rest.period.DailyPeriodParser;
import uk.ac.ebi.quickgo.rest.headers.HttpHeader;
import uk.ac.ebi.quickgo.rest.headers.HttpHeadersProvider;

import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;

import static java.util.stream.Collectors.toList;
import static uk.ac.ebi.quickgo.common.validator.OntologyIdPredicate.isValidECOTermId;
import static uk.ac.ebi.quickgo.common.validator.OntologyIdPredicate.isValidGOTermId;

/**
 * Configure the beans related to the operation of the restful service - id validation helpers and configuration
 * object for page sizes.
 *
 * @author Tony Wardell
 * Date: 17/01/2017
 * Time: 13:32
 * Created with IntelliJ IDEA.
 *
 */
@Configuration
@EnableConfigurationProperties(OntologyRestProperties.class)
public class OntologyRestConfig {

    private Logger LOGGER = LoggerFactory.getLogger(OntologyRestConfig.class);
    public static final String CACHE_CONTROL_HEADER = "public, max-age";
    private static final String PERIOD_DELIMITER = ",";

    @Bean
    public OntologyPagingConfig ontologyPagingConfig(
            @Value("${ontology.default_page_size:25}") int defaultPageSize) {
        return () -> defaultPageSize;
    }

    @Bean
    public OBOControllerValidationHelper goValidationHelper(@Value("${ontology.max_page_size:600}") int maxPageSize) {
        return new OBOControllerValidationHelperImpl(maxPageSize, isValidGOTermId());
    }

    @Bean
    public OBOControllerValidationHelper ecoValidationHelper(@Value("${ontology.max_page_size:600}") int maxPageSize) {
        return new OBOControllerValidationHelperImpl(maxPageSize, isValidECOTermId());
    }

    /**
     * Configure a HttpHeadersProvider instance to write required response HTTP headers.
     * @return HttpHeadersProvider instance
     */
    @Bean
    public HttpHeadersProvider httpHeadersProvider(RemainingTimeSupplier maxAgeProvider) {
        HttpHeader headerSource = new HttpHeader(HttpHeaders.CACHE_CONTROL, CACHE_CONTROL_HEADER,
                                                 () -> Long.toString(maxAgeProvider.get().getSeconds()));
        return new HttpHeadersProvider(Collections.singletonList(headerSource));
    }

    @Bean
    RemainingTimeSupplier maxAgeProvider(@Value("${ontology.caching.allowed.period}") String cachingAllowedPeriodValue,
            DailyPeriodParser dailyPeriodParser) {
        Collection<Period> cachingAllowedPeriods = null;
        if (Objects.nonNull(cachingAllowedPeriodValue)) {
            String[] periods = cachingAllowedPeriodValue.split(PERIOD_DELIMITER);
            try {
                cachingAllowedPeriods = Arrays.stream(periods)
                                              .map(dailyPeriodParser::parse)
                                              .filter(Optional::isPresent)
                                              .map(Optional::get)
                                              .collect(toList());
            } catch (Exception e) {
                LOGGER.error("Failed to load caching allowed periods for ontology", e);
            }
        }
        return
                new RemainingTimeSupplier(Objects.nonNull(cachingAllowedPeriods) ? cachingAllowedPeriods : new
                        ArrayList<>());
    }

    @Bean
    DailyPeriodParser periodParser() {
        return new DailyPeriodParser();
    }

    public interface OntologyPagingConfig {
        int defaultPageSize();
    }
}

@@ -242,21 +242,26 @@
 est.
-period.Period
+headers.HttpHeader
 ;%0Aim
@@ -292,34 +292,33 @@
 est.
-period.RemainingTimeSuppli
+headers.HttpHeadersProvid
 er;%0A
@@ -403,32 +403,78 @@
 go.rest.
-headers.HttpHead
+period.Period;%0Aimport uk.ac.ebi.quickgo.rest.period.PeriodPars
 er;%0Aimpo
@@ -503,33 +503,34 @@
 est.
-headers.HttpHeadersProvid
+period.RemainingTimeSuppli
 er;%0A
@@ -3015,38 +3015,22 @@
     
-DailyPeriodParser daily
 PeriodP
+arser p
 arse
@@ -3367,20 +3367,9 @@
 map(
-dailyPeriodP
+p
 arse
@@ -3702,18 +3702,82 @@
 ontology
-%22,
+ using %22 + cachingAllowedPeriodValue,%0A                            
  e);%0A   
@@ -3918,20 +3918,16 @@
 eriods :
- new
 %0A       
@@ -3947,19 +3947,55 @@
     
-Arra
+                          Collections.empt
 yList
-%3C%3E
 ());
@@ -4016,21 +4016,16 @@
 ean%0A    
-Daily
 PeriodPa

Use PeriodParser as the reference type in maxAgeProvider, instead of a subclass name. Replace new ArrayList() with Collections.emptyList().