package org.gcube.application.cms.tests.plugins;

import lombok.extern.slf4j.Slf4j;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.Plugin;
import org.gcube.application.cms.plugins.faults.*;
import org.gcube.application.cms.plugins.reports.EventExecutionReport;
import org.gcube.application.cms.plugins.reports.StepExecutionReport;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
import org.gcube.application.cms.plugins.requests.StepExecutionRequest;
import org.gcube.application.cms.tests.TokenSetter;
import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor;
import org.gcube.application.geoportal.common.model.plugins.OperationDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Assert;
import org.junit.Test;

import java.util.Map;

@Slf4j
public class BasicLCPluginTest extends BasicPluginTest{

    @Test
    public void testLifeCycle(){
        for (Map.Entry<String, Plugin> entry : plugins.entrySet()) {
            String s = entry.getKey();
            Plugin p = entry.getValue();
            if (p.getDescriptor().getType().equals(LifecycleManagerDescriptor.LIFECYCLE_MANAGER_TYPE)) {
                System.out.println("Testing LC Manager " + p.getDescriptor());
                LifecycleManager ip = (LifecycleManager) p;
                try {
                    LifecycleManagerDescriptor descriptor =(LifecycleManagerDescriptor)p.getDescriptor();
                    log.info("EVENTS ARE {}",descriptor.getSupportedEvents());
                    for(Map.Entry<String, OperationDescriptor> e : descriptor.getSupportedEvents().entrySet()){
                        EventExecutionRequest req = prepareEventRequest(e.getKey());
                        log.info("Launching request {} ",req);
                        EventExecutionReport rep = testEvent(ip,req);
                        log.info("Report is {} ",rep);
                    }

                    if(descriptor.getSupportedSteps()!=null) {
                        log.info("STEPS ARE {}", descriptor.getSupportedEvents());
                        for (Map.Entry<String, OperationDescriptor> e : descriptor.getSupportedSteps().entrySet()) {
                            StepExecutionRequest req = prepareStepRequest(e.getKey());
                            log.info("Launching request {} ", req);
                            StepExecutionReport rep = testStep(ip, req);
                            log.info("Report is {} ", rep);
                        }
                    }

                    ip.init().validate();

                    if (GCubeTest.isTestInfrastructureEnabled()) {
                        TokenSetter.set(GCubeTest.getContext());
                        ip.initInContext().validate();
                    }
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                    Assert.fail("Unable to Init " + p.getDescriptor().getId());
                }
            }
        }

    }


    protected StepExecutionRequest prepareStepRequest(String stepId){
        return new StepExecutionRequest(getUCD(),getCurrentUser(),getContext(),getBasicProject(),stepId);
    };

    protected EventExecutionRequest prepareEventRequest(String event){
        return new EventExecutionRequest(getUCD(),getCurrentUser(),getContext(),getBasicProject(),event);
    };

    
    protected EventExecutionReport testEvent(LifecycleManager lc, EventExecutionRequest r) throws InvalidPluginRequestException, EventException {
        return lc.onEvent(r);
    }
    protected StepExecutionReport testStep(LifecycleManager lc, StepExecutionRequest r) throws InvalidPluginRequestException, StepException, InvalidProfileException, StepException, ConfigurationException, InsufficientPrivileges {
        return lc.performStep(r);
    }
}
