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 = create(toplevelBc);
        int productVersionId = bcSetGenerator.createProduct(name, productVersion);
        bcSetGenerator.createBCSet(bcSetName, productVersionId, new ArrayList<>(ids));
        return productVersionId;
    }

    private Set<Integer> create(ProjectHiearchy hiearchy) throws Exception {
        Set<Integer> deps = new HashSet<>();
        if (hiearchy.isSelected()) {

            for (ProjectHiearchy dep : hiearchy.getDependencies().orElseGet(Collections::emptySet)) {
                deps.addAll(create(dep));
            }

            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, deps);
                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);
            deps.add(bc.getId());
        }
        return deps;
    }

    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;
    }
}

@@ -1299,16 +1299,41 @@
 r%3E ids =
+ new HashSet%3C%3E();%0A       
  create(
@@ -1342,16 +1342,21 @@
 plevelBc
+, ids
 );%0A     
@@ -1572,28 +1572,23 @@
 private 
-Set%3C
 Integer
-%3E
  create(
@@ -1611,16 +1611,47 @@
 hiearchy
+, Set%3CInteger%3E allDependencyIds
 ) throws
@@ -1688,74 +1688,51 @@
 er%3E 
-deps = new HashSet%3C%3E();%0A        if (hiearchy.isSelected()) %7B%0A%0A    
+nextLevelDependencyIds = new HashSet%3C%3E();%0A%0A
     
@@ -1841,23 +1841,74 @@
     
-    dep
+if (dep.isSelected()) %7B%0A                nextLevelDependencyId
 s.add
-All
 (cre
@@ -1914,16 +1914,34 @@
 eate(dep
+, allDependencyIds
 ));%0A    
@@ -1950,21 +1950,27 @@
       %7D%0A
-%0A
     
+    %7D%0A%0A
         
@@ -2016,36 +2016,32 @@
 ject();%0A        
-    
 BuildConfigurati
@@ -2054,38 +2054,35 @@
 te bcc;%0A        
-  
-  
 if
+ 
 (project.isUseEx
@@ -2092,22 +2092,19 @@
 ingBc())
+ 
 %7B%0A
-    
         
@@ -2220,28 +2220,24 @@
             
-  
-  
 bcc = bc.orE
@@ -2344,23 +2344,17 @@
     
-    
 %7D
+ 
 else
+ 
 %7B%0A
-    
     
@@ -2381,19 +2381,37 @@
 roject, 
-dep
+nextLevelDependencyId
 s);%0A    
@@ -2418,22 +2418,19 @@
         
-   
- 
 if
+ 
 (project
@@ -2444,16 +2444,17 @@
 eRepo())
+ 
 %7B%0A      
@@ -2467,21 +2467,14 @@
     
- 
-   
 try
+ 
 %7B%0A
-    
     
@@ -2653,20 +2653,16 @@
         
-    
 bcc.setS
@@ -2703,18 +2703,16 @@
     
-    
 %7D
+ 
 catch
+ 
 (Exc
@@ -2721,16 +2721,17 @@
 tion ex)
+ 
 %7B%0A      
@@ -2744,20 +2744,16 @@
         
- 
-   
 log.erro
@@ -2796,34 +2796,26 @@
             
-    %7D%0A    
+%7D%0A
             
@@ -2820,34 +2820,26 @@
   %7D%0A        
-    %7D%0A    
+%7D%0A
         Buil
@@ -2905,15 +2905,23 @@
     
-    dep
+allDependencyId
 s.ad
@@ -2935,25 +2935,16 @@
 tId());%0A
-        %7D
 %0A       
@@ -2951,20 +2951,26 @@
  return 
-deps
+bc.getId()
 ;%0A    %7D%0A

Fix finalizer so build configurations don't link to all transitive dependencies