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.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.Relationship;
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.*;
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 = "concessioni/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,
                new Access(),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);

        Access access =new Access();
        access.setLicense("test-license");
        access.setPolicy(AccessPolicy.RESTRICTED);

        // 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,
                access,filename);

        return doc;
    }

    // Not automatic, needs generation of locked project
//    @Test
//    public void testUnlock() throws Exception {
//        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
//        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());
//    }

}
