package se.capeit.dev.xunittestrunner;

import jetbrains.buildServer.dotNet.DotNetConstants;
import jetbrains.buildServer.requirements.Requirement;
import jetbrains.buildServer.requirements.RequirementType;
import jetbrains.buildServer.serverSide.InvalidProperty;
import jetbrains.buildServer.serverSide.PropertiesProcessor;
import jetbrains.buildServer.serverSide.RunType;
import jetbrains.buildServer.serverSide.RunTypeRegistry;
import jetbrains.buildServer.web.openapi.PluginDescriptor;
import org.jetbrains.annotations.NotNull;

import java.util.*;

public class XUnitTestRunType extends RunType {
    private final PluginDescriptor pluginDescriptor;

    public XUnitTestRunType(@NotNull final RunTypeRegistry runTypeRegistry, final PluginDescriptor pluginDescriptor)
    {
        this.pluginDescriptor = pluginDescriptor;
        runTypeRegistry.registerRunType(this);
    }

    @NotNull
    @Override
    public String getType() {
        return StringConstants.RunTypeName;
    }

    @NotNull
    @Override
    public String getDisplayName() {
        return "xUnit";
    }

    @NotNull
    @Override
    public String getDescription() {
        return "Runs tests written in xUnit";
    }

    @Override
    public PropertiesProcessor getRunnerPropertiesProcessor() {
        return new PropertiesProcessor() {
            public Collection<InvalidProperty> process(Map<String, String> properties) {
                ArrayList<InvalidProperty> toReturn = new ArrayList<InvalidProperty>();
                if (!properties.containsKey(StringConstants.ParameterName_IncludedAssemblies) ||
                        properties.get(StringConstants.ParameterName_IncludedAssemblies).isEmpty())
                    toReturn.add(new InvalidProperty(StringConstants.ParameterName_IncludedAssemblies,
                            "Please enter what assemblies should be included"));

                // TODO: Validate runner supports platform/runtime

                return toReturn;
            }
        };
    }

    @Override
    public String getEditRunnerParamsJspFilePath() {
        return pluginDescriptor.getPluginResourcesPath("editRunnerParameters.jsp");
    }

    @Override
    public String getViewRunnerParamsJspFilePath() {
        return pluginDescriptor.getPluginResourcesPath("viewRunnerParameters.jsp");
    }

    @Override
    public Map<String, String> getDefaultRunnerProperties() {
        HashMap<String, String> defaults = new HashMap<String, String>();
        defaults.put(StringConstants.ParameterName_XUnitVersion, "2.1.0");
        defaults.put(StringConstants.ParameterName_Platform, Platforms.MSIL);
        defaults.put(StringConstants.ParameterName_RuntimeVersion, Runtime.dotNET45);

        return defaults;
    }

    @NotNull
    @Override
    public List<Requirement> getRunnerSpecificRequirements(@NotNull Map<String, String> runParameters) {
        List<Requirement> requirements = new ArrayList<Requirement>(super.getRunnerSpecificRequirements(runParameters));

        String runtime = runParameters.get(StringConstants.ParameterName_RuntimeVersion);
        String frameworkMatcher = null;
        if (runtime.equals(Runtime.dotNET35)) {
            frameworkMatcher = "3.5"; // Match just 3.5
        }
        else if (runtime.equals(Runtime.dotNET40)) {
            frameworkMatcher = "4.[0-9\\.]+"; // Match any 4.x
        }
        else if (runtime.equals(Runtime.dotNET45)) {
            frameworkMatcher = "4.[56](\\.[0-9]+)?"; // Match 4.5+
        }

        String platform = runParameters.get(StringConstants.ParameterName_Platform);
        String platformMatcher = null;
        if (platform.equals(Platforms.MSIL)) {
            platformMatcher = "(x86|x64)";
        }
        else {
            platformMatcher = platform;
        }

        requirements.add(new Requirement("Exists=>DotNetFramework" + frameworkMatcher + "_" + platformMatcher, null, RequirementType.EXISTS));
        requirements.add(new Requirement("teamcity.tool." + StringConstants.ToolName, null, RequirementType.EXISTS));

        return requirements;
    }

    @NotNull
    @Override
    public String describeParameters(@NotNull Map<String, String> parameters) {
        StringBuilder sb = new StringBuilder();
        sb.append("Version ");
        sb.append(parameters.get(StringConstants.ParameterName_XUnitVersion));

        sb.append(" (");
        sb.append(parameters.get(StringConstants.ParameterName_Platform));
        sb.append("/");
        sb.append(parameters.get(StringConstants.ParameterName_RuntimeVersion));
        sb.append(")");
        
        sb.append("\nIncluded assemblies: ");
        sb.append(parameters.get(StringConstants.ParameterName_IncludedAssemblies));

        String excluded = parameters.get(StringConstants.ParameterName_ExcludedAssemblies);
        if(excluded != null && !excluded.trim().isEmpty()) {
            sb.append("\nExcluded assemblies: ");
            sb.append(excluded);
        }
        return sb.toString();
    }
}

@@ -3091,16 +3091,1203 @@
 rsion);%0A
+        String platform = runParameters.get(StringConstants.ParameterName_Platform);%0A        // 1.0 of the plugin did not set runtime/platform, because only a single version was supported%0A        // For upgrades we need to manually set runtime/platform%0A        if(runtime == null %7C%7C platform == null) %7B%0A            String xUnitVersion = runParameters.get(StringConstants.ParameterName_XUnitVersion);%0A            switch(xUnitVersion) %7B%0A                case %221.9.2%22:%0A                    runtime = Runtime.dotNET40;%0A                    platform = Platforms.MSIL;%0A                    break;%0A                case %222.0.0%22:%0A                    runtime = Runtime.dotNET45;%0A                    platform = Platforms.MSIL;%0A                    break;%0A                default:%0A                    // The famous last words, %22This should never happen%22. But, if it does, let's just ask the user to%0A                    // re-set the values in their build config%0A                    requirements.add(new Requirement(%22xUnit-plugin: Invalid configuration, unable to build. Please verify build step settings%22, null, RequirementType.EXISTS));%0A                    return requirements;%0A            %7D%0A        %7D%0A%0A
         
@@ -4310,32 +4310,32 @@
 Matcher = null;%0A
-
         if (runt
@@ -4693,93 +4693,8 @@
  %7D%0A%0A
-        String platform = runParameters.get(StringConstants.ParameterName_Platform);%0A
     

Fix upgrades from 1.0 not having all parameters set. Fixes issue# 15