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

import org.bson.Document;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field;
import org.gcube.application.geoportal.common.rest.InterfaceConstants;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.gcube.application.geoportal.service.BasicServiceTestUnit;
import org.junit.Assert;
import org.junit.Test;

import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import java.time.LocalDateTime;

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

public class DummyProjectTest extends AbstractProfiledDocumentsTests{


    // Try set releazione scavo
    String parentPath="section";
    String fieldName="fileset";
    String fieldDefinition="section."+Field.CHILDREN+"[?(@.fileset)]";

    String filename = "sample.tif";


    @Override
    protected WebTarget baseTarget() {
        String testProfileId="basic";
        return super.baseTarget().path(testProfileId);
    }





    @Test
    public void registerNew() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Document doc = new Document("field","value");
        doc.put("startTime", LocalDateTime.now());
        System.out.println(Serialization.write(doc));
        Project project = createNew(doc);
        System.out.println(Serialization.write(project));
        assertTrue(project.getTheDocument().containsKey("field"));
        assertTrue(project.getTheDocument().getString("field").equals("value"));
    }


    @Test
    public void edit() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Project doc=createNew(new Document());
        String beforeJson=doc.getTheDocument().toJson();
        doc.getTheDocument().put("someStrangeField","someOtherRandomValue");
        String edited=doc.getTheDocument().toJson();
        Assert.assertNotEquals(beforeJson,doc.getTheDocument().toJson());
        doc= BasicServiceTestUnit.check(baseTarget().path(doc.getId()).request(MediaType.APPLICATION_JSON).
                put(Entity.entity(doc.getTheDocument(), MediaType.APPLICATION_JSON)), Project.class);
        Assert.assertEquals(edited,doc.getTheDocument().toJson());
    }

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

        Project doc = createWithFileSet();
        JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson());
        assertTrue("Relazione exists",wrapper.getMatchingPaths("section").size()==1);
        RegisteredFileSet fs = Serialization.convert(wrapper.getByPath("section.fileset").get(0),RegisteredFileSet.class);
        assertTrue(fs.getPayloads().size()==1);
        assertTrue(fs.getString("customField").equals("customFieldValue"));

        // test replace
        doc = upload(
                new StorageUtils(),
                doc.getId(),
                parentPath,fieldName,
                fieldDefinition,
                new Document("customField","customFieldValue"),
                RegisterFileSetRequest.ClashOptions.REPLACE_EXISTING,
                filename);

        wrapper = new JSONPathWrapper(doc.getTheDocument().toJson());
        assertTrue("Relazione exists",wrapper.getMatchingPaths("section").size()==1);
        fs = Serialization.convert(wrapper.getByPath("section.fileset").get(0),RegisteredFileSet.class);
        assertTrue(fs.getPayloads().size()==1);
        assertTrue(fs.getString("customField").equals("customFieldValue"));

    }


    @Test
    public void testSimpleDelete() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        Document baseDoc=new Document();
        baseDoc.put("section",new Document("title","My Title"));
        Project doc = createNew(baseDoc);

    }

    @Test
    public void testFullDelete() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        delete(createWithFileSet().getId(),true);
    }







    private Project createWithFileSet() throws Exception {
        Document baseDoc=new Document();
        baseDoc.put("section",new Document("title","My Title"));

        Project doc = createNew(baseDoc);




        // INSERT ONE, MERGE INFO (NB default values already exist)
        doc = upload(
                new StorageUtils(),
                doc.getId(),
                parentPath,fieldName,
                fieldDefinition,
                new Document("customField","customFieldValue"),
                RegisterFileSetRequest.ClashOptions.REPLACE_EXISTING,
                filename);

        return doc;
    }

    @Test
    public void testUnlock() throws Exception {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        // Not automatic, needs generation of locked project
        assumeTrue(false);
        String id = "627e87bb02ad3d1a2e0e9e18";
        String ucd = "profiledConcessioni";
        Project p =check(target(InterfaceConstants.Methods.PROJECTS).path(ucd).path(InterfaceConstants.Methods.FORCE_UNLOCK).path(id).request(MediaType.APPLICATION_JSON).
                put(Entity.entity("", MediaType.APPLICATION_JSON)), Project.class);
        assertNull(p.getLock());
    }


//    @Test
//    public void testSDI() throws Exception {
//        // Create new
//        Project doc = createNew(new Document("posizionamentoScavo",new Document("title","Mio pos")));
//
//        // register filesets
//        doc = upload(
//                new StorageUtils(),
//                doc.getId(),
//                "posizionamentoScavo","fileset",
//                "posizionamentoScavo."+Field.CHILDREN+"[?(@.fileset)]",
//               null,
//                RegisterFileSetRequest.ClashOptions.REPLACE_EXISTING,
//                "pos.shp","pos.shx");
//
//        System.out.println("Registered posizionamento, result is "+ Serialization.write(doc));
//
//        // invoke step SUBMIT-FOR-REVIEW
//        StepExecutionRequest req=new StepExecutionRequest();
//        req.setStepID("SUBMIT-FOR-REVIEW");
//        doc=step(doc.getId(),req);
//        System.out.println(doc);
//        if(doc.getLifecycleInformation().getErrorMessages()!=null) {
//            System.out.println("ERROR MESSAGES");
//            doc.getLifecycleInformation().getErrorMessages().forEach(s -> System.out.println(s));
//        }
//        if(doc.getLifecycleInformation().getWarningMessages()!=null) {
//            System.out.println("WARNING MESSAGES");
//            doc.getLifecycleInformation().getWarningMessages().forEach(s -> System.out.println(s));
//        }
//
//        assertTrue(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK));
//
//        JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson());
//        RegisteredFileSet fs = Serialization.convert(wrapper.getByPath("$..fileset").get(0),RegisteredFileSet.class);
//        assertTrue(fs!=null);
//        assertTrue(fs.getPayloads().size()==2);
//        assertTrue(fs.getMaterializations().size()>0);
//
//
//        for(Object matObj : wrapper.getByPath("$..[?(@."+ Materialization.TYPE +" == '"+GCubeSDILayer.GCUBE_SDY_LAYER_TYPE+"' )]")){
//            GCubeSDILayer layer = Serialization.convert(matObj, GCubeSDILayer.class);
//            System.out.println("Checking Layer : "+layer);
//            assertTrue(layer.getType().equals(GCubeSDILayer.GCUBE_SDY_LAYER_TYPE));
//            assertTrue(layer.getOGCLinks().size()>0);
//            assertTrue(layer.getPlatformInfo().size()>0);
//            assertTrue(layer.getBBox()!=null);
//        }
//
//        // Checking platform info GeoServer
//        for(Object platformObj : wrapper.getByPath("$..[?(@."+ Materialization.TYPE +" == 'GeoServer' )]")){
//            Document platform=Serialization.asDocument(platformObj);
//                assertTrue(platform.containsKey("layerName"));
//                assertTrue(platform.containsKey("workspace"));
//                assertTrue(platform.containsKey("storeName"));
//                assertTrue(platform.containsKey("persistencePath"));
//                assertTrue(platform.get("files",List.class).size()==2);
//        }
//
//
//        req.setStepID("APPROVE DRAFT");
//        doc=step(doc.getId(),req);
//        if(doc.getLifecycleInformation().getErrorMessages()!=null) {
//            System.out.println("ERROR MESSAGES");
//            doc.getLifecycleInformation().getErrorMessages().forEach(s -> System.out.println(s));
//        }
//        if(doc.getLifecycleInformation().getWarningMessages()!=null) {
//            System.out.println("WARNING MESSAGES");
//            doc.getLifecycleInformation().getWarningMessages().forEach(s -> System.out.println(s));
//        }
//
//        assertTrue(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK));
//
//    }

}
