/*
 * Copyright 2015-2017 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.opencga.catalog.utils;

import org.opencb.commons.datastore.core.QueryOptions;
import org.opencb.opencga.core.models.Account;
import org.opencb.opencga.core.models.Study;
import org.opencb.opencga.core.models.acls.AclParams;
import org.opencb.opencga.core.config.Configuration;
import org.opencb.opencga.catalog.exceptions.CatalogException;
import org.opencb.opencga.catalog.managers.CatalogManager;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by pfurio on 08/06/16.
 */
public final class CatalogDemo {

    private CatalogDemo() {

    }

    /**
     * Populates the database with dummy data.
     *
     * @param configuration Catalog configuration file.
     * @param force Used in the case where a database already exists with the same name. When force = true, it will override it.
     * @throws CatalogException when there is already a database with the same name and force is false.
     * @throws URISyntaxException when there is a problem parsing the URI read from the configuration file.
     */
    public static void createDemoDatabase(Configuration configuration, boolean force) throws CatalogException, URISyntaxException {
        CatalogManager catalogManager = new CatalogManager(configuration);
        if (catalogManager.existsCatalogDB()) {
            if (force) {
                catalogManager.deleteCatalogDB(force);
            } else {
//                throw new CatalogException("A database called " + catalogConfiguration.getDatabase().getDatabase() + " already exists");
                throw new CatalogException("A database called " + catalogManager.getCatalogDatabase() + " already exists");
            }
        }
        catalogManager.installCatalogDB();
        try {
            populateDatabase(catalogManager);
        } catch (IOException e) {
            throw new CatalogException(e.getMessage());
        }
    }

    private static void populateDatabase(CatalogManager catalogManager) throws CatalogException, IOException {
        // Create users
        Map<String, String> userSessions = new HashMap<>(5);
        for (int i = 1; i <= 5; i++) {
            String id = "user" + i;
            String name = "User" + i;
            String password = id + "_pass";
            String email = id + "@gmail.com";
            catalogManager.getUserManager().create(id, name, email, password, "organization", 2000L, Account.FULL, null);
            userSessions.put(id, catalogManager.getUserManager().login(id, password));
        }

        // Create one project per user
        Map<String, Long> projects = new HashMap<>(5);
        for (Map.Entry<String, String> userSession : userSessions.entrySet()) {
            projects.put(userSession.getKey(), catalogManager.getProjectManager().create("DefaultProject", "default",
                    "Description", "Organization", "Homo sapiens", null, null, "GrCh38",
                    new QueryOptions(), userSession.getValue()).first().getId());
        }

        // Create two studies per user
        Map<String, List<Long>> studies = new HashMap<>(5);
        for (Map.Entry<String, String> userSession : userSessions.entrySet()) {
            long projectId = projects.get(userSession.getKey());
            List<Long> studiesTmp = new ArrayList<>(2);
            for (int i = 1; i <= 2; i++) {
                String name = "Name of study" + i;
                String alias = "study" + i;
                studiesTmp.add(catalogManager.getStudyManager().create(String.valueOf(projectId), name, alias, Study.Type.FAMILY, null,
                        "Description of " + alias, null, null, null, null, null, null, null, null, userSession.getValue()).first().getId());
            }
            studies.put(userSession.getKey(), studiesTmp);
        }

        /*
        SHARE STUDY1 OF USER1
         */
        long studyId = studies.get("user1").get(0);
        String sessionId = userSessions.get("user5");

        // user5 will have the role "admin"
        Study.StudyAclParams aclParams2 = new Study.StudyAclParams("", AclParams.Action.ADD, "admin");
        catalogManager.getStudyManager().updateAcl(Long.toString(studyId), "user5", aclParams2, userSessions.get("user1")).get(0);
        // user5 will add the rest of users. user2, user3 and user4 go to group "members"
        catalogManager.getStudyManager().createGroup(Long.toString(studyId), "analyst", "user2,user3,user4", sessionId);
        //        // @members will have the role "analyst"
        Study.StudyAclParams aclParams1 = new Study.StudyAclParams("", AclParams.Action.ADD, "analyst");
        catalogManager.getStudyManager().updateAcl(Long.toString(studyId), "@analyst", aclParams1, sessionId).get(0);
        //        // Add anonymous user to the role "denyAll". Later we will give it permissions to see some concrete samples.
        Study.StudyAclParams aclParams = new Study.StudyAclParams("", AclParams.Action.ADD, "locked");
        catalogManager.getStudyManager().updateAcl(Long.toString(studyId), "*", aclParams, sessionId).get(0);
    }

}

@@ -734,16 +734,67 @@
 ccount;%0A
+import org.opencb.opencga.core.models.GroupParams;%0A
 import o
@@ -4734,132 +4734,31 @@
 ill 
-have the role %22admin%22%0A        Study.StudyAclParams aclParams2 = new Study.StudyAclParams(%22%22, AclParams.Action.ADD, %22admin%22);
+be in the @admins group
 %0A   
@@ -4793,35 +4793,37 @@
 Manager().update
-Acl
+Group
 (Long.toString(s
@@ -4831,16 +4831,43 @@
 udyId), 
+%22@admins%22, new GroupParams(
 %22user5%22,
@@ -4871,19 +4871,48 @@
 5%22, 
-acl
+Group
 Params
-2,
+.Action.ADD),%0A               
  use
@@ -4934,23 +4934,16 @@
 user1%22))
-.get(0)
 ;%0A      

fix demo script