package org.gcube.application.geoportal.common;

import lombok.extern.slf4j.Slf4j;
import org.gcube.application.geoportal.common.rest.InterfaceConstants;
import org.gcube.application.geoportal.common.utils.ContextUtils;
import org.gcube.application.geoportal.common.utils.StorageUtils;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.gcube.contentmanagement.blobstorage.service.IClient;
import org.gcube.contentmanager.storageclient.wrapper.AccessType;
import org.gcube.contentmanager.storageclient.wrapper.MemoryType;
import org.gcube.contentmanager.storageclient.wrapper.StorageClient;
import org.junit.Before;
import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import static org.junit.Assume.assumeTrue;

@Slf4j
public class StorageUtilsTest {

    IClient client= null;

    @Before
    public void init(){
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        TokenSetter.set(GCubeTest.getContext());
        client=new StorageClient(InterfaceConstants.SERVICE_CLASS, InterfaceConstants.SERVICE_NAME,
                ContextUtils.getCurrentCaller(), AccessType.SHARED, MemoryType.VOLATILE).getClient();
    }

    private String getFileID() throws FileNotFoundException {
        return client.put(true).LFile(
                new FileInputStream("../test-data/concessioni/relazione.pdf")).
                RFile(StorageUtils.getUniqueString());
    }

    private String getURL(String id){
        return client.getHttpsUrl().RFile(id);
    }

    @Test
    public void testParallelStorage() throws FileNotFoundException, InterruptedException {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        ExecutorService service = Executors.newFixedThreadPool(10);
        LocalDateTime start=LocalDateTime.now();
        AtomicLong executed = new AtomicLong(0);
        AtomicLong launched = new AtomicLong(0);

        String id=getFileID();
        //for 100 secs
        while(Duration.between(start,LocalDateTime.now()).
                compareTo(Duration.of(100, ChronoUnit.SECONDS))<0){
            service.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(getURL(id));
                    } catch (Throwable t) {
                        log.info("Too many connections... ");
                    }finally{
                        executed.incrementAndGet();
                        try {Thread.sleep(500);} catch (InterruptedException i) {}
                    }
                }
            });
            launched.incrementAndGet();
        }

        while (!service.awaitTermination(2, TimeUnit.MINUTES)) {
            log.info("Waiting .. completed {}, out of {} ",executed.get(),launched.get());
            if(executed.get()==launched.get()) service.shutdown();
        }
    }

    @Test
    public void testSerialStorage() throws FileNotFoundException {
        assumeTrue(GCubeTest.isTestInfrastructureEnabled());
        //get client
        client=new StorageClient(InterfaceConstants.SERVICE_CLASS, InterfaceConstants.SERVICE_NAME,
                ContextUtils.getCurrentCaller(), AccessType.SHARED, MemoryType.VOLATILE).getClient();

        //put file
        String id= client.put(true).LFile(
                new FileInputStream("../test-data/concessioni/relazione.pdf")).
                RFile(StorageUtils.getUniqueString());

        for(int i = 0; i<1000;i++){
            //get ID
            System.out.println(client.getHttpsUrl().RFile(id));
        }
    }



}
