package org.radarcns.management.config;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.radarcns.management.domain.SourceData;
import org.radarcns.management.domain.SourceType;
import org.radarcns.management.repository.SourceDataRepository;
import org.radarcns.management.repository.SourceTypeRepository;
import org.radarcns.management.service.catalog.CatalogSourceData;
import org.radarcns.management.service.catalog.CatalogSourceType;
import org.radarcns.management.service.catalog.SourceTypeResponse;
import org.radarcns.management.service.mapper.CatalogSourceDataMapper;
import org.radarcns.management.service.mapper.CatalogSourceTypeMapper;
import org.radarcns.management.web.rest.util.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * Upon start of Spring application, this class automatically import the source-types
 * provided by Catalog server in Radar-Schemas.
 * This will be executed when a valid URL of the catalog server is provided and
 * enableAutoImport is set to true.
 */
@Component
public class SourceTypeLoader implements CommandLineRunner {

    private Logger log = LoggerFactory.getLogger(SourceTypeLoader.class);

    @Autowired
    private SourceTypeRepository sourceTypeRepository;

    @Autowired
    private SourceDataRepository sourceDataRepository;

    @Autowired
    private ManagementPortalProperties managementPortalProperties;

    @Autowired
    private CatalogSourceTypeMapper catalogSourceTypeMapper;

    @Autowired
    private CatalogSourceDataMapper catalogSourceDataMapper;

    public void run(String... args) {

        String catalogServerUrl = managementPortalProperties.getCatalogueServer().getServerUrl();

        if (managementPortalProperties.getCatalogueServer().isEnableAutoImport()) {

            try {
                if (HttpUtil.isReachable(new URL(catalogServerUrl))) {
                    RestTemplate restTemplate = new RestTemplate();
                    ResponseEntity<SourceTypeResponse> catalogues = null;
                    log.debug("Requesting source-types from catalogue server...");
                    catalogues = restTemplate
                        .getForEntity(
                            managementPortalProperties.getCatalogueServer().getServerUrl(),
                            SourceTypeResponse.class);
                    SourceTypeResponse catalogueDTO = catalogues.getBody();
                    List<CatalogSourceType> catalogSourceTypes = new ArrayList<>();
                    if (catalogueDTO.getPassiveSources() != null) {
                        catalogSourceTypes.addAll(catalogueDTO.getPassiveSources());
                    }
                    if (catalogueDTO.getActiveSources() != null) {
                        catalogSourceTypes.addAll(catalogueDTO.getActiveSources());
                    }
                    if (catalogueDTO.getMonitorSources() != null) {
                        catalogSourceTypes.addAll(catalogueDTO.getMonitorSources());
                    }

                    for (CatalogSourceType catalogSourceType : catalogSourceTypes) {
                        SourceType sourceType = catalogSourceTypeMapper
                            .catalogSourceTypeToSourceType(catalogSourceType);
                        sourceTypeRepository.save(sourceType);

                        for (CatalogSourceData catalogSourceData : catalogSourceType.getData()) {
                            SourceData sourceData = catalogSourceDataMapper
                                .catalogSourceDataToSourceData(catalogSourceData);
                            sourceData.sourceDataName(
                                sourceType.getProducer() + "_" + sourceType.getModel() + "_"
                                    + sourceType
                                    .getCatalogVersion() + "_" + sourceData.getSourceDataType());
                            sourceData.sourceType(sourceType);
                            sourceDataRepository.save(sourceData);
                        }
                    }

                    log.info("Completed source-type import from catalog-server");
                }
                else {
                    log.warn("Catalog Service {} is unreachable: {}", catalogServerUrl);
                }
            } catch (MalformedURLException e) {
                log.warn("Invalid Url provided for Catalog server url {} : {}", catalogServerUrl, e.getMessage());
            }
        } else {
            log.info("Auto source-type import is disabled");
        }

    }
}

@@ -141,24 +141,50 @@
 .util.List;%0A
+import java.util.Objects;%0A
 import org.r
@@ -2845,32 +2845,48 @@
              if 
+(Objects.nonNull
 (catalogueDTO.ge
@@ -2898,32 +2898,25 @@
 iveSources()
- != null
+)
 ) %7B%0A        
@@ -3029,32 +3029,48 @@
              if 
+(Objects.nonNull
 (catalogueDTO.ge
@@ -3081,32 +3081,25 @@
 iveSources()
- != null
+)
 ) %7B%0A        
@@ -3219,16 +3219,32 @@
      if 
+(Objects.nonNull
 (catalog
@@ -3272,16 +3272,9 @@
 es()
- != null
+)
 ) %7B%0A
@@ -3645,48 +3645,576 @@
     
-sourceTypeRepository.save(sourceType);%0A%0A
+// check whether a source-type is already available with given config%0A                        if (!sourceTypeRepository%0A                            .findOneWithEagerRelationshipsByProducerAndModelAndVersion(%0A                                sourceType.getProducer(), sourceType.getModel(),%0A                                sourceType.getCatalogVersion()).isPresent()) %7B%0A                            // create new source-type%0A                            sourceTypeRepository.save(sourceType);%0A%0A                            // create source-data for the new source-type%0A    
     
@@ -4289,24 +4289,57 @@
 ogSourceType
+%0A                                
 .getData()) 
@@ -4364,24 +4364,28 @@
             
+   
+ 
 SourceData s
@@ -4416,24 +4416,28 @@
 eDataMapper%0A
+    
             
@@ -4499,32 +4499,200 @@
 logSourceData);%0A
+                                // sourceDataName should be unique%0A                                // generated by combining sourceDataType and source-type configs%0A    
                 
@@ -4730,16 +4730,20 @@
 taName(%0A
+    
         
@@ -4863,16 +4863,20 @@
         
+    
 + source
@@ -4912,24 +4912,28 @@
             
+  
+  
 .getCatalogV
@@ -4959,16 +4959,57 @@
 urceData
+%0A                                        
 .getSour
@@ -5019,24 +5019,28 @@
 ataType());%0A
+    
             
@@ -5110,32 +5110,36 @@
                 
+    
 sourceDataReposi
@@ -5153,32 +5153,398 @@
 ve(sourceData);%0A
+                            %7D%0A                        %7D else %7B%0A                            // skip for existing source-types%0A                            log.info(%22Source-type %7B%7D is already available %22,%0A                                sourceType.getProducer() + %22_%22 + sourceType.getModel() + %22_%22%0A                                    + sourceType.getCatalogVersion());%0A
                 

check whether a source-type is already existing before creating a new one