package com.thinkbiganalytics.metadata.modeshape.catalog;

/*-
 * #%L
 * kylo-metadata-modeshape
 * %%
 * Copyright (C) 2017 - 2018 ThinkBig Analytics, a Teradata Company
 * %%
 * 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.
 * #L%
 */

import com.thinkbiganalytics.kylo.catalog.ConnectorPluginManager;
import com.thinkbiganalytics.kylo.catalog.rest.model.ConnectorPluginDescriptor;
import com.thinkbiganalytics.kylo.catalog.spi.ConnectorPlugin;
import com.thinkbiganalytics.metadata.api.MetadataAccess;
import com.thinkbiganalytics.metadata.api.PostMetadataConfigAction;
import com.thinkbiganalytics.metadata.api.catalog.Connector;
import com.thinkbiganalytics.metadata.api.catalog.ConnectorProvider;
import com.thinkbiganalytics.metadata.api.catalog.DataSetProvider;
import com.thinkbiganalytics.metadata.api.catalog.DataSourceProvider;
import com.thinkbiganalytics.metadata.modeshape.catalog.connector.JcrConnectorProvider;
import com.thinkbiganalytics.metadata.modeshape.catalog.dataset.JcrDataSet;
import com.thinkbiganalytics.metadata.modeshape.catalog.dataset.JcrDataSetProvider;
import com.thinkbiganalytics.metadata.modeshape.catalog.datasource.JcrDataSourceProvider;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Configuration
public class CatalogMetadataConfig {
    
    private static final Logger log = LoggerFactory.getLogger(CatalogMetadataConfig.class);


    @Bean
    public ConnectorProvider connectorProvider() {
        return new JcrConnectorProvider();
    }

    @Bean
    public DataSourceProvider dataSourceProvider() {
        return new JcrDataSourceProvider();
    }

    @Bean
    public DataSetProvider dataSetProvider() {
        return new JcrDataSetProvider();
    }

    @Bean
    public PostMetadataConfigAction connectorPluginSyncAction(ConnectorPluginManager pluginMgr, MetadataAccess metadata) {
        return () -> {
            metadata.commit(() -> {
                List<ConnectorPlugin> plugins = pluginMgr.getPlugins();
                Map<String, Connector> connectorMap = connectorProvider().findAll(true).stream().collect(Collectors.toMap(Connector::getPluginId, c -> c));

                for (ConnectorPlugin plugin : plugins) {
                    Connector connector = connectorMap.get(plugin.getId());
                    ConnectorPluginDescriptor descr = plugin.getDescriptor();

                    if (connector != null) {
                        connectorMap.get(plugin.getId()).setActive(true);
                        connectorMap.remove(plugin.getId());
                    } else {
                        String title = descr.getTitle();
                        connector = connectorProvider().create(plugin.getId(), title);
                    }

                    connector.setIconColor(descr.getColor());
                    connector.setIcon(descr.getIcon());
                    if (StringUtils.isNotBlank(descr.getFormat())) {
                        connector.getSparkParameters().setFormat(descr.getFormat());
                    }
                }

                // Any left over connectors that do not have a corresponding plugin should be either made inactive if they at 
                // least one data source, or removed if they don't.
                for (Connector connector : connectorMap.values()) {
                    if (connector.getDataSources().isEmpty()) {
                        connectorProvider().deleteById(connector.getId());
                    } else {
                        connector.setActive(false);
                    }
                }
            }, MetadataAccess.SERVICE);
        };
    }
}

@@ -1129,24 +1129,107 @@
 .Connector;%0A
+import com.thinkbiganalytics.metadata.api.catalog.ConnectorAlreadyExistsException;%0A
 import com.t
@@ -1277,32 +1277,32 @@
 nectorProvider;%0A
-
 import com.think
@@ -1414,32 +1414,99 @@
 SourceProvider;%0A
+import com.thinkbiganalytics.metadata.modeshape.JcrMetadataAccess;%0A
 import com.think
@@ -1581,84 +1581,8 @@
 er;%0A
-import com.thinkbiganalytics.metadata.modeshape.catalog.dataset.JcrDataSet;%0A
 impo
@@ -1797,16 +1797,56 @@
 gUtils;%0A
+import org.modeshape.jcr.api.Workspace;%0A
 import o
@@ -2090,16 +2090,43 @@
 ctors;%0A%0A
+import javax.jcr.Session;%0A%0A
 @Configu
@@ -2173,13 +2173,9 @@
 g %7B%0A
-    
 %0A
+
     
@@ -2596,32 +2596,32 @@
    %7D%0A%0A    @Bean%0A
-
     public PostM
@@ -2723,24 +2723,1164 @@
 metadata) %7B%0A
+        try %7B%0A            return doPluginSyncAction(pluginMgr, metadata);%0A        %7D catch (ConnectorAlreadyExistsException e) %7B%0A            log.warn(%22Encountered an error attempting to synchronize plugins%22, e);%0A            log.info(%22Rebuilding modeshape indexes to ensure the are accurately synchronized with the data.   Please be patient as this may take a long time!%22);%0A%0A            try %7B%0A                reindex(metadata);%0A                return doPluginSyncAction(pluginMgr, metadata);%0A            %7D catch (ConnectorAlreadyExistsException e2) %7B%0A                log.error(%22Unrecoverable fatal exception. Encountered connector already exists after synchronizing modeshape indexes%22, e2);%0A                throw e2;%0A            %7D%0A        %7D%0A    %7D%0A%0A%0A%0A    private void reindex(MetadataAccess metadata) %7B%0A        metadata.commit(() -%3E %7B%0A            Session session = JcrMetadataAccess.getActiveSession();%0A            Workspace workspace = (Workspace) session.getWorkspace();%0A            workspace.reindex();%0A        %7D);%0A    %7D%0A%0A%0A    private PostMetadataConfigAction doPluginSyncAction(ConnectorPluginManager pluginMgr, MetadataAccess metadata) %7B%0A
         retu

add backup plan to connector sync to reindex modeshape and try again if needed