package jetbrains.buildServer.flex.service;

import jetbrains.buildServer.serverSide.ProjectManager;
import jetbrains.buildServer.serverSide.SBuildServer;
import jetbrains.buildServer.serverSide.SBuildType;
import jetbrains.buildServer.serverSide.SProject;
import jetbrains.buildServer.serverSide.artifacts.SArtifactDependency;
import jetbrains.buildServer.serverSide.dependency.Dependency;
import org.springframework.context.support.ApplicationObjectSupport;

import java.util.*;

/**
 * Author: Nikita.Skvortsov
 * Date: 12/10/10
 */
public class DependenciesDataService extends ApplicationObjectSupport {
    private SBuildServer mySBuildServer;

    public DependenciesDataService(SBuildServer sBuildServer) {
        mySBuildServer = sBuildServer;
    }

    public Map<String,String> getProjectsIdNames() {
        Map<String, String> result = new HashMap<String,String>();
        final List<SProject> projects = mySBuildServer.getProjectManager().getProjects();
        for (SProject project : projects) {
            result.put(project.getProjectId(),project.getName());
        }
        return result;
    }

    public Map<String,String> getBuildConfigurations(String projectId) {
        final Map<String, String> result = new HashMap<String, String>();
        final SProject project = mySBuildServer.getProjectManager().findProjectById(projectId);
        final List<SBuildType> buildTypes = project.getBuildTypes();
        for (SBuildType buildType : buildTypes) {
            result.put(buildType.getBuildTypeId(), buildType.getName());
        }
        return result;
    }

    public Map<String,List<String[]>> getDepData(String buildTypeId) {
        final ArrayList<String[]> inboundNodes = new ArrayList<String[]>();
        final ArrayList<String[]> outboundNodes = new ArrayList<String[]>();
        final Map<String, List<String[]>> result = new HashMap<String, List<String[]>>(2);

        final ProjectManager projectManager = mySBuildServer.getProjectManager();
        final SBuildType buildType = projectManager.findBuildTypeById(buildTypeId);
        final List<SBuildType> allBuildTypes = projectManager.getAllBuildTypes();

        traceReferences(buildType, outboundNodes);
        traceDependencies(buildType, inboundNodes);

        if (inboundNodes.size() == 0 && outboundNodes.size() == 0) {
            inboundNodes.add(new String[] {buildType.getName(),""});
            result.put("noDeps", inboundNodes);
        } else {
            result.put("inbound", inboundNodes);
            result.put("outbound", outboundNodes);
        }

        return result;
    }

    private void traceDependencies(SBuildType buildType, ArrayList<String[]> depsList) {
        final List<Dependency> dependencies = buildType.getDependencies();
        final List<SArtifactDependency> artifactDependencies = buildType.getArtifactDependencies();
        for (Dependency dependency : dependencies) {
            final SBuildType dependOn = dependency.getDependOn();
            depsList.add(new String[] {dependOn.getName(), buildType.getName()});
            traceDependencies(dependOn, depsList);
        }

        for (SArtifactDependency artifactDependency : artifactDependencies) {
            final SBuildType dependOn = mySBuildServer.getProjectManager().findBuildTypeById(
                    artifactDependency.getSourceBuildTypeId());
            depsList.add(new String[] {dependOn.getName(), buildType.getName()});
            traceDependencies(dependOn, depsList);
        }
    }

    private void traceReferences(SBuildType buildType, ArrayList<String[]> refList) {
        final List<SBuildType> references = buildType.getArtifactsReferences();
        references.addAll(buildType.getDependencyReferences());
        for (SBuildType reference : references) {
            refList.add(new String[]{buildType.getName(), reference.getName()});
            traceReferences(reference,refList);
        }
    }


}
