package org.jboss.da.bc.backend.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import javax.ejb.Stateless;
import javax.inject.Inject;

import org.jboss.da.bc.backend.api.BCSetGenerator;
import org.jboss.da.bc.backend.api.BcChecker;
import org.jboss.da.bc.backend.api.Finalizer;
import org.jboss.da.bc.backend.api.RepositoryCloner;
import org.jboss.da.bc.model.ProjectDetail;
import org.jboss.da.bc.model.ProjectHiearchy;
import org.jboss.da.communication.pnc.api.PNCConnector;
import org.jboss.da.communication.pnc.model.BuildConfiguration;
import org.jboss.da.communication.pnc.model.BuildConfigurationCreate;
import org.jboss.da.scm.api.SCMType;
import org.slf4j.Logger;

/**
 *
 * @author Honza Brázdil <jbrazdil@redhat.com>
 */
@Stateless
public class FinalizerImpl implements Finalizer {

    @Inject
    private Logger log;

    @Inject
    private PNCConnector pnc;

    @Inject
    private BCSetGenerator bcSetGenerator;

    @Inject
    private RepositoryCloner repoCloner;

    @Inject
    private BcChecker bcFinder;

    @Override
    public Integer createBCs(String name, String productVersion, ProjectHiearchy toplevelBc,
            String bcSetName) throws Exception {
        Set<Integer> ids = new HashSet<>();
        create(toplevelBc, ids);
        int productVersionId = bcSetGenerator.createProduct(name, productVersion);
        bcSetGenerator.createBCSet(bcSetName, productVersionId, new ArrayList<>(ids));
        return productVersionId;
    }

    private Integer create(ProjectHiearchy hiearchy, Set<Integer> allDependencyIds) throws Exception {
        Set<Integer> nextLevelDependencyIds = new HashSet<>();

        for (ProjectHiearchy dep : hiearchy.getDependencies().orElseGet(Collections::emptySet)) {
            if (dep.isSelected()) {
                nextLevelDependencyIds.add(create(dep, allDependencyIds));
            }
        }

        ProjectDetail project = hiearchy.getProject();
        BuildConfigurationCreate bcc;
        if (project.isUseExistingBc()) {
            Optional<BuildConfiguration> bc = bcFinder.lookupBcByScm(project.getScmUrl(), project.getScmRevision());
            bcc = bc.orElseThrow(() -> new IllegalStateException("useExistingBC is true, but there is no BC to use."));
        } else {
            bcc = toBC(project, nextLevelDependencyIds);
            if (project.isCloneRepo()) {
                try {
                    String newScmUrl = repoCloner.cloneRepository(project.getScmUrl(), project.getScmRevision(), SCMType.GIT, "Repository of " + project.getGav());
                    bcc.setScmRepoURL(newScmUrl);
                } catch (Exception ex) {
                    log.error("Failed to clone repo.", ex);
                }
            }
        }
        BuildConfiguration bc = pnc.createBuildConfiguration(bcc);
        allDependencyIds.add(bc.getId());

        return bc.getId();
    }

    private BuildConfigurationCreate toBC(ProjectDetail project, Set<Integer> deps) {
        BuildConfigurationCreate bc = new BuildConfigurationCreate();
        bc.setBuildScript(project.getBuildScript());
        bc.setDependencyIds(new ArrayList<>(deps));
        bc.setDescription(project.getDescription());
        bc.setEnvironmentId(project.getEnvironmentId());
        bc.setName(project.getName());
        bc.setProjectId(project.getProjectId());
        bc.setScmRepoURL(project.getScmUrl());
        bc.setScmRevision(project.getScmRevision());
        return bc;
    }
}

@@ -1956,24 +1956,63 @@
 %7D%0A        %7D%0A
+        %0A        BuildConfiguration bc;
 %0A        Pro
@@ -2059,46 +2059,8 @@
 ();%0A
-        BuildConfigurationCreate bcc;%0A
     
@@ -2137,17 +2137,25 @@
 ration%3E 
-b
+optionalB
 c = bcFi
@@ -2235,21 +2235,28 @@
       bc
-c
  = 
-b
+optionalB
 c.orElse
@@ -2377,16 +2377,41 @@
         
+BuildConfigurationCreate 
 bcc = to
@@ -2443,24 +2443,76 @@
 ndencyIds);%0A
+            bc = pnc.createBuildConfiguration(bcc);%0A
             
@@ -2923,74 +2923,8 @@
   %7D%0A
-        BuildConfiguration bc = pnc.createBuildConfiguration(bcc);
 %0A   
@@ -2962,17 +2962,16 @@
 tId());%0A
-%0A
         

Fix using existing BCs in BC generator