package org.gcube.application.geoportal.clients;

import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.gcube.application.cms.tests.Tests;
import org.gcube.application.geoportal.client.utils.Serialization;
import org.gcube.application.geoportal.common.faults.InvalidRequestException;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
import org.gcube.application.geoportal.common.model.configuration.Configuration;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.access.Access;
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject;
import org.gcube.application.geoportal.common.model.rest.CreateRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.DeleteRelationshipRequest;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.rest.Projects;
import org.gcube.application.geoportal.common.utils.FileSets;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Test;

import java.io.File;
import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicLong;

import static org.gcube.application.geoportal.client.utils.Serialization.write;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

@Slf4j
public class ProfiledDocumentsTest<M extends Project,C extends Projects<M>> extends GenericUseCases {


    @Test
    public void registerNew() throws RemoteException, JsonProcessingException, FileNotFoundException, InvalidRequestException {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Projects<M> client = (Projects<M>) getClient();

        Document theDoc= Document.parse("{\n" +
                "\"section\" :{\n" +
                "\t\"titolo\" : \"mio titolo\"}}");

        theDoc.put("startTime", LocalDateTime.now());

        Project p =client.createNew(theDoc);

        log.debug("Registered project (AS JSON) : {}", write(p));


    }


    @Test
    public void testAccess() throws FileNotFoundException, RemoteException, InvalidRequestException, JsonProcessingException {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Projects<M> client = (Projects<M>) getClient();

        Document theDoc= Document.parse("{\n" +
                "\"section\" :{\n" +
                "\t\"titolo\" : \"mio titolo\"}}");

        theDoc.put("startTime", LocalDateTime.now());

        Project p =client.createNew(theDoc);

        RegisterFileSetRequest fsRequest = prepareRequest();

        Access access = new Access();
        access.setLicense("CC0-1.0");
        access.setPolicy(AccessPolicy.RESTRICTED);
        fsRequest.setToSetAccess(access);

        p=client.registerFileSet(p.getId(),fsRequest);

        log.info("Registered fileset. Result is {}", Serialization.write(p));
        RegisteredFileSet f= Serialization.convert(new JSONPathWrapper(p.getTheDocument().toJson()).
                getByPath(fsRequest.getParentPath()+"."+fsRequest.getFieldName()).get(0),RegisteredFileSet.class);

        assertEquals(Serialization.convert(f.getAccess(),Access.class).getPolicy(),AccessPolicy.RESTRICTED);

    }

    @Test
    public void getConfiguration() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Projects<M> client = (Projects<M>) getClient();
        Configuration config=client.getConfiguration();
        System.out.println("Configuration is "+ config);
    }


    @Test
    public void list() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Projects<M> client = (Projects<M>) getClient();
        AtomicLong counter=new AtomicLong(0);
        client.query(new QueryRequest()).forEachRemaining( M -> counter.incrementAndGet());
        System.out.println("Found "+counter.get()+" elements");
        System.out.println("Getting JSON ");
        System.out.println(client.queryForJSON(new QueryRequest()));
    }

    @Test
    public void scanStatusByID() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Projects<M> client = (Projects<M>) getClient();
        AtomicLong counter=new AtomicLong(0);
        client.query(new QueryRequest()).forEachRemaining( m -> {
            System.out.print(counter.incrementAndGet()+ ", ID : "+m.getId());
            try {
                M proj=client.getById(m.getId());
                System.out.println("... OK.. STATUS : "+proj.getLifecycleInformation());
            } catch (RemoteException e) {
                System.err.println(" Error with "+m.getId());
                System.err.println(e);
                System.out.println("... ERRR !!!!");
            }
        });
    }


}
