/*
 * Copyright 2017 Crown Copyright
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package stroom.datasource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import stroom.ExternalService;
import stroom.ServiceDiscoverer;
import stroom.query.api.v1.DocRef;
import stroom.security.SecurityContext;
import stroom.util.spring.StroomScope;

import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Component
@Scope(StroomScope.PROTOTYPE)
public class DataSourceProviderRegistry {
    private final Map<ExternalService, DataSourceProvider> providers = new HashMap<>();
    private final SecurityContext securityContext;
    private final ServiceDiscoverer serviceDiscoverer;

    @Inject
    public DataSourceProviderRegistry(final SecurityContext securityContext,
                                      final ServiceDiscoverer serviceDiscoverer) {
        this.securityContext = securityContext;
        this.serviceDiscoverer = serviceDiscoverer;

        //TODO this means we register services explicitly on boot so if the service happens
        //to be down at that point then we will never have access to it.
        //Think whenever anybody needs a data source provider we use the service discoverer to
        //find the required datasourceprovider.  Not sure if curator caches the KVs locally or whether
        //it means a round trip to ZK.  If not we may need to hold a short term cache.
        //I think we can do away with the providers map above, instead treating ServiceDiscoverer as the map

        register(ExternalService.INDEX);
        register(ExternalService.STROOM_STATS);
        register(ExternalService.SQL_STATISTICS);
    }

    public Optional<DataSourceProvider> getDataSourceProvider(final String docRefType) {

            ExternalService dataSourceService = ExternalService.docRefTypeToServiceMap.get(docRefType);
            return Optional.ofNullable(providers.get(dataSourceService));
    }

    public Optional<DataSourceProvider> getDataSourceProvider(final DocRef dataSourceRef) {

        return Optional.ofNullable(dataSourceRef)
                .map(DocRef::getType)
                .flatMap(this::getDataSourceProvider);
    }

    private void register(ExternalService externalService) {
        Optional<String> indexAddress = serviceDiscoverer.getAddress(externalService);

        indexAddress.ifPresent(url ->
                providers.put( externalService, new RemoteDataSourceProvider( securityContext, url)
        ));
    }
}

@@ -933,56 +933,8 @@
 ct;%0A
-import java.util.HashMap;%0Aimport java.util.Map;%0A
 impo
@@ -1044,96 +1044,8 @@
 y %7B%0A
-    private final Map%3CExternalService, DataSourceProvider%3E providers = new HashMap%3C%3E();%0A
     
@@ -1423,610 +1423,292 @@
 er;%0A
-%0A
     
+%7D%0A%0A
     
-//TODO this means we register services explicitly on boot so if the service happens%0A        //to be down at that point then we will never have access to it.%0A        //Think whenever anybody needs a data s
+public Optional%3CRemoteDataSourceProvider%3E getDataS
 ource
- p
+P
 rovider
- we use the service discoverer to%0A        //find the required
+(final String docRefType) %7B%0A        ExternalService
  data
-s
+S
 ource
-provider.  Not sure if curator caches the KVs locally or whether%0A        //it means a round trip to ZK.  If not we may need to hold a short term cache.%0A        //I think we can do away with the providers map above, instead treating ServiceDiscoverer as the map%0A%0A        register(External
+Service = ExternalService.docRefTypeToServiceMap.get(docRefType);%0A        Optional%3CString%3E url = serviceDiscoverer.getAddress(dataSource
 Service
-.INDEX
 );%0A
+%0A 
     
@@ -1717,367 +1717,159 @@
   re
-gister(ExternalService.STROOM_STATS);%0A        register(ExternalService.SQL_STATISTICS);%0A
+turn url%0A         
     
-%7D%0A%0A
     
-public Optional%3CDataSourceProvider%3E getDataSourceProvider(final String docRefType) %7B%0A%0A            ExternalService dataSourceService = ExternalService.docRefTypeToServiceMap.get(docRefType);%0A            return Optional.ofNullable(providers.get(dataSourceService
+.map(address -%3E Optional.of(new RemoteDataSourceProvider(securityContext, address)))%0A                 .orElse(Optional.empty(
 ));%0A
@@ -1895,16 +1895,22 @@
 ptional%3C
+Remote
 DataSour
@@ -1973,17 +1973,16 @@
 eRef) %7B%0A
-%0A
         
@@ -2125,313 +2125,7 @@
    %7D
-%0A%0A    private void register(ExternalService externalService) %7B%0A        Optional%3CString%3E indexAddress = serviceDiscoverer.getAddress(externalService);%0A%0A        indexAddress.ifPresent(url -%3E%0A                providers.put( externalService, new RemoteDataSourceProvider( securityContext, url)%0A        ));%0A    %7D
 %0A%7D%0A

Remove provider cache