package ee.elinyo.teamcity.plugins.ansible.agent;

import java.util.ArrayList;
import java.util.List;

import jetbrains.buildServer.RunBuildException;
import jetbrains.buildServer.agent.artifacts.ArtifactsWatcher;
import jetbrains.buildServer.agent.runner.BuildServiceAdapter;
import jetbrains.buildServer.agent.runner.ProcessListener;
import jetbrains.buildServer.agent.runner.ProgramCommandLine;
import jetbrains.buildServer.agent.runner.SimpleProgramCommandLine;

import org.jetbrains.annotations.NotNull;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;

import ee.elinyo.teamcity.plugins.ansible.common.AnsibleCommand;
import ee.elinyo.teamcity.plugins.ansible.common.AnsibleRunConfig;

public class AnsibleRunService extends BuildServiceAdapter {
    
    protected static final Logger LOG = Logger.getInstance(AnsibleRunService.class.getName());
    
    private ArtifactsWatcher artifactsWatcher;

    public AnsibleRunService(ArtifactsWatcher artifactsWatcher) {
        this.artifactsWatcher = artifactsWatcher;
    }

    @Override
    public ProgramCommandLine makeProgramCommandLine() throws RunBuildException {
        AnsibleRunConfig config = new AnsibleRunConfig(getRunnerParameters());
        if (LOG.isDebugEnabled()) {
            LOG.debug("Going to run ansible with parameters: " + config.toString());
        }
        if (AnsibleCommand.CUSTOM_SCRIPT.equals(config.getCommandType())) {
            return makeCustomScriptCommand(config);
        }
        return makeExecutableCommand(config);
    }
    
    private ProgramCommandLine makeExecutableCommand(AnsibleRunConfig config)
            throws RunBuildException {
        String workingDir = getWorkingDirectory().getPath();
        List<String> args = new ArrayList<String>();
        if (!StringUtil.isEmptyOrSpaces(config.getInventory())) {
            args.add("-i");
            args.add(config.getInventory());
        }
        if (StringUtil.isEmptyOrSpaces(config.getPlaybook())) {
            throw new RunBuildException("Ansible playbook should be specified");
        }
        args.add(config.getPlaybook());
        if (!StringUtil.isEmptyOrSpaces(config.getOptions())) {
            String opts = config.getOptions().replace("\n", "").replace("\r", "");
            args.add(opts);
        }
        return new SimpleProgramCommandLine(getEnvironmentVariables(),
                workingDir,
               config.getExecutable(), args);
    }

    private ProgramCommandLine makeCustomScriptCommand(AnsibleRunConfig config) throws RunBuildException {
       // String workingDir = getWorkingDirectory().getPath();
        LOG.warn("Not Implemented");
        throw new RunBuildException("Ansible customs script is not imlemented");
    }

    @NotNull
    @Override
    public List<ProcessListener> getListeners() {
        List<ProcessListener> listeners = new ArrayList<ProcessListener>(super.getListeners());
        listeners.add(new AnsibleOutputListener(getBuild(), getRunnerContext(), artifactsWatcher));
        return listeners;
    }

}

@@ -458,16 +458,78 @@
 andLine;
+%0Aimport jetbrains.buildServer.runner.CommandLineArgumentsUtil;
 %0A%0Aimport
@@ -1820,28 +1820,29 @@
         
-List%3C
 String
-%3E
+Builder
  args = 
@@ -1849,26 +1849,24 @@
 new 
-ArrayList%3CString%3E(
+StringBuilder(%22%22
 );%0A 
@@ -1952,37 +1952,26 @@
 gs.a
-d
+ppen
 d(%22-i
+ 
 %22)
-;%0A            args.ad
+.appen
 d(co
@@ -2171,17 +2171,32 @@
   args.a
-d
+ppend(%22 %22).appen
 d(config
@@ -2292,104 +2292,51 @@
     
-String opts = config.getOptions().replace(%22%5Cn%22, %22%22).replace(%22%5Cr%22, %22%22);%0A            args.add(opts
+args.append(%22 %22).append(config.getOptions()
 );%0A 
@@ -2482,20 +2482,74 @@
 able(), 
-args
+CommandLineArgumentsUtil.extractArguments(args.toString())
 );%0A    %7D

fix command arguments handler