/*
 * Copyright 2015-2020 OpenCB
 *
 * 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 org.opencb.cellbase.lib.impl.core;

import org.opencb.cellbase.core.models.DataRelease;
import org.opencb.commons.datastore.mongodb.MongoDBCollection;
import org.opencb.commons.datastore.mongodb.MongoDataStore;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CellBaseDBAdaptor extends MongoDBAdaptor {

    protected List<DataRelease> dataReleases;
    protected Map<Integer, MongoDBCollection> mongoDBCollectionByRelease;

    public static final String DATA_RELEASE_SEPARATOR = "__v";

    public static String buildCollectionName(String data, int release) {
        String name = data + DATA_RELEASE_SEPARATOR + release;
        return name;
    }

    public Map<Integer, MongoDBCollection> buildCollectionByReleaseMap(String data) {
        Map<Integer, MongoDBCollection> collectionMap = new HashMap<>();
        for (DataRelease dataRelease : dataReleases) {
            if (dataRelease.getCollections().containsKey(data)) {
                String collectionName = dataRelease.getCollections().get(data);
                collectionMap.put(dataRelease.getRelease(), mongoDataStore.getCollection(collectionName));
                if (dataRelease.isActiveByDefault()) {
                    collectionMap.put(0, mongoDataStore.getCollection(collectionName));
                }
            }
        }
        return collectionMap;
    }

    public MongoDBCollection getCollectionByRelease(Map<Integer, MongoDBCollection> collectionMap, Integer dataRelease) {
        int release = dataRelease == null ? 0 : dataRelease;
        if (!collectionMap.containsKey(release)) {
            logger.error("Data release (" + release + ") not found!!");
            return null;
        }
        return collectionMap.get(release);
    }

    public CellBaseDBAdaptor(MongoDataStore mongoDataStore) {
        super(mongoDataStore);
        this.dataReleases = new ReleaseMongoDBAdaptor(mongoDataStore).getAll().getResults();
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("CellBaseDBAdaptor{");
        sb.append("dataReleasse=").append(dataReleases);
        sb.append('}');
        return sb.toString();
    }

    public List<DataRelease> getDataReleases() {
        return dataReleases;
    }

    public CellBaseDBAdaptor setDataReleases(List<DataRelease> dataReleases) {
        this.dataReleases = dataReleases;
        return this;
    }
}

@@ -629,24 +629,80 @@
 impl.core;%0A%0A
+import org.apache.commons.collections4.CollectionUtils;%0A
 import org.o
@@ -1498,24 +1498,84 @@
 ashMap%3C%3E();%0A
+        if (CollectionUtils.isNotEmpty(dataReleases)) %7B%0A    
         for 
@@ -1609,32 +1609,36 @@
 dataReleases) %7B%0A
+    
             if (
@@ -1699,24 +1699,28 @@
             
+    
 String colle
@@ -1779,32 +1779,36 @@
                 
+ 
+   
 collectionMap.pu
@@ -1890,32 +1890,36 @@
                 
+    
 if (dataRelease.
@@ -1937,24 +1937,114 @@
 efault()) %7B%0A
+                        // Associate the default data release to the key 0 in the map%0A    
             
@@ -2127,32 +2127,36 @@
                 
+    
 %7D%0A            %7D%0A
@@ -2145,33 +2145,231 @@
   %7D%0A            
-%7D
+    %7D%0A            %7D%0A        %7D else %7B%0A            // For backward compatibility (i.e., in case data_release collection is missing)%0A            collectionMap.put(0, mongoDataStore.getCollection(data));
 %0A        %7D%0A     
@@ -2355,32 +2355,33 @@
 ta));%0A        %7D%0A
+%0A
         return c
@@ -2631,24 +2631,108 @@
 release)) %7B%0A
+            // If the data release is invalid, it will use the default data release%0A
             
@@ -2742,13 +2742,12 @@
 ger.
-error
+warn
 (%22Da
@@ -2784,16 +2784,48 @@
 ot found
+. Using the default data release
 !!%22);%0A  
@@ -2840,17 +2840,17 @@
   re
-turn null
+lease = 0
 ;%0A  

support backward compatibility (i.e., when the collection data_release is missing), #TASK-592