package org.gcube.application.geoportal.service.profiledDocuments;

import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.cms.serialization.Serialization;
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.identification.SpatialReference;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.rest.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;

import org.junit.Test;

import javax.ws.rs.client.WebTarget;
import java.time.LocalDateTime;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

@Slf4j
public class ProfiledConcessioniTests extends AbstractProfiledDocumentsTests{

    

    @Override
    protected WebTarget baseTarget() {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        String testProfileId="profiledConcessioni";
        return super.baseTarget().path(testProfileId);
    }

    @Test
    public void testSDI() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        UserUtils.DEFAULT_ROLES.add("Data-Manager");
        // Create new

        Document theDoc=Document.parse("{" +
                "\"posizionamentoScavo\" :{\"titolo\" : \"mio titolo\"},\"nome\":\"TEST SDI Extensions\"}");

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

        log.debug("Sending {}",theDoc);
        log.debug("AS JSON : {}",Serialization.write(theDoc));

        Project doc = createNew(theDoc);

        log.debug("Received : {}",doc);
        log.debug("AS JSON : {}",Serialization.write(doc));


        // register filesets
        doc = upload(
                new StorageUtils(),
                doc.getId(),
                "$.posizionamentoScavo",
                "fileset",
                "$.posizionamentoScavo."+ Field.CHILDREN+"[?(@.fileset)]",
                null,
                RegisterFileSetRequest.ClashOptions.MERGE_EXISTING,new Access(),
                "concessioni/pos.SHP");


        System.out.println("Registered posizionamento, result is "+ Serialization.write(doc));
        // invoke step SUBMIT-FOR-REVIEW
        StepExecutionRequest submitReq=new StepExecutionRequest();
        submitReq.setStepID("SUBMIT-FOR-REVIEW");
//        doc=step(doc.getId(),submitReq);
        doc=step(doc.getId(),submitReq);
        System.out.println(doc);
        assertTrue(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK));


        // invoke step Publish

        StepExecutionRequest approveDraftReq=new StepExecutionRequest();
        approveDraftReq.setStepID("APPROVE-SUBMITTED");
        doc=step(doc.getId(),approveDraftReq);
        System.out.println(doc);
        assertTrue(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK));
        assertTrue(doc.getIdentificationReferenceByType(SpatialReference.SPATIAL_REFERENCE_TYPE).size()==1);
        System.out.println("Project "+doc.getId()+" published with spatial reference "+doc.getIdentificationReferenceByType(SpatialReference.SPATIAL_REFERENCE_TYPE).get(0));


        // check deletion
        delete(doc.getId(),true);
        System.out.println("Deleted.");





    }

    @Test
    public void testGetById() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        getById("63cffb238f66b84c444dae4f");
        System.out.println("Done");
    }


    @Test
    public void testRelations() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());

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

        Project doc1 = createNew(theDoc);
        Project doc2 = createNew(theDoc);

        String rel = "follows";
        String reverse = "precedes";
        log.info("Creating relation ");
        doc1 = setRelation(doc1,doc2.getId(),null,rel);

        log.debug("JSON Doc 1 : {}",Serialization.write(doc1));
        // check relation
        assertTrue(doc1.getRelationships().size()==1);
        assertEquals(doc1.getRelationships().get(0).getTargetID(),doc2.getId());
        assertEquals(doc1.getRelationships().get(0).getTargetUCD(),doc2.getProfileID());
        assertEquals(doc1.getRelationships().get(0).getRelationshipName(),rel);

        // check reverse
        doc2=getById(doc2.getId());
        log.debug("JSON Doc 2 : {}",Serialization.write(doc2));
        assertTrue(doc2.getRelationships().size()==1);
        assertEquals(doc2.getRelationships().get(0).getTargetID(),doc1.getId());
        assertEquals(doc2.getRelationships().get(0).getTargetUCD(),doc1.getProfileID());
        assertEquals(doc2.getRelationships().get(0).getRelationshipName(),reverse);

        StepExecutionRequest stepReq = new StepExecutionRequest();
        stepReq.setStepID("SUBMIT-FOR-REVIEW");

        step(doc1.getId(),stepReq);


        // clean
        doc2 = deleteRelation(doc2, doc1.getId(), doc1.getProfileID(),reverse);
        log.debug("JSON Doc 2 : {}",Serialization.write(doc2));
        assertTrue(doc2.getRelationships()==null || doc2.getRelationships().isEmpty());

        doc1 = getById(doc1.getId());
        log.debug("JSON Doc 1 : {}",Serialization.write(doc1));
        assertTrue(doc1.getRelationships()==null || doc1.getRelationships().isEmpty());


    }

    @Test
    public void delete() throws Exception {
        Document theDoc=Document.parse("{\n" +
                "\"posizionamentoScavo\" :{\n" +
                "\t\"titolo\" : \"mio titolo\"}}");

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

        log.debug("sendi");

        Project doc = createNew(theDoc);



    }
}
