package org.gcube.application.geoportal.client.utils;

import lombok.extern.slf4j.Slf4j;
import org.gcube.application.geoportal.common.model.legacy.*;
import org.gcube.application.geoportal.common.model.rest.AddSectionToConcessioneRequest;
import org.gcube.application.geoportal.common.rest.MongoConcessioni;
import org.gcube.application.geoportal.common.utils.StorageUtils;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

@Slf4j
public class ConcessioniUtils {
    
    public static final Concessione clone(MongoConcessioni client,String toCloneId) throws Exception {
        StorageUtils storage=new StorageUtils();
            log.info("Cloning {}",toCloneId);
            Concessione src = client.getById(toCloneId);
            // copy
            Concessione copied = Serialization.read(Serialization.write(src),Concessione.class);
            // cleanup
            copied.setMongo_id(null);
            copied.setLastUpdateTime(null);
            copied.setLastUpdateUser(null);
            copied.setFolderId(null);
            copied.setReport(null);
            copied.setCreationTime(null);
            copied.setCreationUser(null);
            copied.setId(0);
            copied.setVersion("1.0.0");

            copied.setRelazioneScavo(null);
            copied.setAbstractRelazione(null);
            copied.setPosizionamentoScavo(null);
            copied.setImmaginiRappresentative(null);
            copied.setPianteFineScavo(null);


            copied = client.createNew(copied);


            //Handle Files

            copied.setRelazioneScavo(clean(src.getRelazioneScavo()));
            copied=client.replace(copied);
            AddSectionToConcessioneRequest req=asCopyRequest(src.getRelazioneScavo(),storage);
            if(req.getStreams()!=null&&!req.getStreams().isEmpty())
                copied=client.registerFileSet(copied.getMongo_id(),req);

            copied.setAbstractRelazione(clean(src.getAbstractRelazione()));
            copied=client.replace(copied);
            req=asCopyRequest(src.getAbstractRelazione(),storage);
            if(req.getStreams()!=null&&!req.getStreams().isEmpty())
                copied=client.registerFileSet(copied.getMongo_id(),req);


            copied.setPosizionamentoScavo(clean(src.getPosizionamentoScavo()));
            copied=client.replace(copied);
            req=asCopyRequest(src.getPosizionamentoScavo(),storage);
            if(req.getStreams()!=null&&!req.getStreams().isEmpty())
                copied=client.registerFileSet(copied.getMongo_id(),req);
            
            if(src.getImmaginiRappresentative()!=null&&src.getImmaginiRappresentative().size()>0) {
                copied.setImmaginiRappresentative(new ArrayList<>());
                for (int i = 0; i < src.getImmaginiRappresentative().size(); i++) {
                    copied.getImmaginiRappresentative().add(clean(src.getImmaginiRappresentative().get(i)));
                    copied=client.replace(copied);
                    req=asCopyRequest(src.getImmaginiRappresentative().get(i),storage);
                    req.setDestinationPath(Concessione.Paths.imgByIndex(i));
                    if(req.getStreams()!=null&&!req.getStreams().isEmpty())
                        copied=client.registerFileSet(copied.getMongo_id(),req);
                }
            }

            if(src.getPianteFineScavo()!=null&&src.getPianteFineScavo().size()>0) {
                copied.setPianteFineScavo(new ArrayList<>());
                for (int i = 0; i < src.getPianteFineScavo().size(); i++) {
                    copied.getPianteFineScavo().add(clean(src.getPianteFineScavo().get(i)));
                    copied=client.replace(copied);
                    req=asCopyRequest(src.getPianteFineScavo().get(i),storage);
                    req.setDestinationPath(Concessione.Paths.piantaByIndex(i));
                    if(req.getStreams()!=null&&!req.getStreams().isEmpty())
                        copied=client.registerFileSet(copied.getMongo_id(),req);
                }
            }

            log.info("Cloned {} into {} ",src.getMongo_id(),copied.getMongo_id());
            return copied;
    }

    private static <T extends AssociatedContent> AddSectionToConcessioneRequest asCopyRequest(T content, StorageUtils storage) throws IOException {
        AddSectionToConcessioneRequest request = new AddSectionToConcessioneRequest();
        request.setStreams(new ArrayList<>());
        if(content.getActualContent()!=null) {
            for (PersistedContent persistedContent : content.getActualContent()) {
                if (persistedContent instanceof WorkspaceContent) {
                    WorkspaceContent wc = (WorkspaceContent) persistedContent;
                    request.getStreams().add(storage.putOntoStorage(new URL(wc.getLink()).openStream(), wc.getName()));
                }
            }
        }

        String path = null;
        if(content instanceof LayerConcessione) path = Concessione.Paths.POSIZIONAMENTO;
        else if (content instanceof RelazioneScavo) path = Concessione.Paths.RELAZIONE;
        else if (content instanceof AbstractRelazione) path = Concessione.Paths.ABSTRACT_RELAZIONE;
        request.setDestinationPath(path);
        return request;
    }
    
    private static <T extends AssociatedContent> T clean(T content) throws IOException {
        T toReturn = (T) Serialization.read(Serialization.write(content),content.getClass());
        toReturn.setMongo_id(null);
        toReturn.setCreationTime(null);
        toReturn.setId(0);
        toReturn.setActualContent(new ArrayList<>());

        if(content instanceof LayerConcessione) {
            ((LayerConcessione)toReturn).setLayerName(null);
            ((LayerConcessione)toReturn).setLayerID(null);
            ((LayerConcessione)toReturn).setBbox(null);
            ((LayerConcessione)toReturn).setLayerUUID(null);
            ((LayerConcessione)toReturn).setWorkspace(null);
            ((LayerConcessione)toReturn).setWmsLink(null);
        }
        return toReturn;
    }
}
