package org.gcube.application.cms.usecases;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.client.legacy.ConcessioniManagerI;
import org.gcube.application.geoportal.client.utils.Serialization;
import org.gcube.application.geoportal.common.model.legacy.AssociatedContent;
import org.gcube.application.geoportal.common.model.legacy.Concessione;
import org.gcube.application.geoportal.common.model.legacy.PersistedContent;
import org.gcube.application.geoportal.common.model.legacy.WorkspaceContent;
import org.gcube.common.storagehub.client.dsl.FileContainer;
import org.gcube.common.storagehub.client.dsl.StorageHubClient;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.statefulMongoConcessioni;

@Slf4j
/*
Imports Json concessioni into import<TIME-MILLIS>
 */
public class Import {


    public static void main(String[] args) throws Exception {

//        Path dir=Files.createTempDirectory(System.currentTimeMillis()+"");

        File dir=new File("import"+System.currentTimeMillis());
        dir.mkdirs();
        String sourceContext="/d4science.research-infrastructures.eu/D4OS/GeoNA-Prototype";
//        String sourceContext="/pred4s/preprod/preVRE";


        Boolean saveFilesLocally=false;


        // GET FOM SOURCE
        TokenSetter.set(sourceContext);

        StorageHubClient sgClient=new StorageHubClient();


        ConcessioniManagerI sourceManager= statefulMongoConcessioni().build();

        ArrayList<Concessione> found=new ArrayList<>();
        Map<String,String> errors = new HashMap<>();


        sourceManager.getList().forEachRemaining(concessione -> found.add(concessione));
        System.out.println("Loaded "+found.size()+" elements, saving them..");
        found.forEach((Concessione c)-> {
            try {
                File currentFolder = new File(dir.toString(), c.getMongo_id() + "");
                currentFolder.mkdirs();

                //Load locally
                if(saveFilesLocally) {
                    // POSIZIONAMENTO
                    loadFiles(c.getPosizionamentoScavo(), new File(currentFolder, "pos"), sgClient);
                    // RELAZIONE
                    loadFiles(c.getRelazioneScavo(), new File(currentFolder, "rel"), sgClient);
                    // IMGs
                    for (int i = 0; i < c.getImmaginiRappresentative().size(); i++)
                        loadFiles(c.getImmaginiRappresentative().get(i), new File(currentFolder, "imgs_" + i), sgClient);

                    // Piante
                    for (int i = 0; i < c.getPianteFineScavo().size(); i++)
                        loadFiles(c.getPianteFineScavo().get(i), new File(currentFolder, "pianta_" + i), sgClient);
                }
                PrintWriter w = new PrintWriter(new File(currentFolder, c.getId() + ".json"));
                w.append(Serialization.write(c));
                w.flush();
                w.close();

            } catch (Throwable t ){
                log.error("Unable to load {}", c.getMongo_id(), t);
                errors.put(c.getMongo_id(),t.getMessage());
            }

        });

        System.out.println("Imported "+found.size()+" elements into "+dir.getAbsolutePath());
        System.out.println("Errors count "+errors.size());
        errors.forEach((s, s2) -> System.out.println("Error for "+s+" : "+s2));
    }




    // NB baseDIR/conc_id/pos | pianta_i | imgs_i | other_i /

    private static int loadFiles(AssociatedContent c, File directory, StorageHubClient sgHub) throws IOException, StorageHubException {
        int count=0;
        if (c == null) {
            log.warn("Content is null for path {}",directory.getAbsolutePath());
        } else if (c.getActualContent() == null) {
            log.warn("Content {} is empty for path {}",c.getId(),directory.getAbsolutePath());
        }else {
            for (PersistedContent content : c.getActualContent()) {
                if (content instanceof WorkspaceContent) {
                    FileContainer item = sgHub.open(((WorkspaceContent) content).getStorageID()).asFile();
                    WorkspaceContent wc = (WorkspaceContent) content;
                    File dest = new File(directory, item.get().getName());
                    dest.getParentFile().mkdirs();
                    dest.createNewFile();
                    IOUtils.copy(item.getPublicLink().openStream(), new FileOutputStream(dest));
                    count++;
                }
            }
            log.info("Put {} files into {} ", count, directory.getAbsolutePath());
        }
        return count;
    };


}
