package org.jonnyzzz.teamcity.ant;

import jetbrains.buildServer.messages.serviceMessages.ServiceMessage;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Eugene Petrenko (eugene.petrenko@gmail.com)
 *
 */
public class TeamCityServiceMessageTask extends Task {
  @Nullable private String myName = null;
  @Nullable private String myValue = null;
  private final List<KeyValuePart> myArguments = new ArrayList<KeyValuePart>();

  public void setName(@Nullable String name) {
    myName = name;
  }

  public void setValue(@Nullable String value) {
    myValue = value;
  }

  @NotNull
  public KeyValuePart createParam() {
    final KeyValuePart part = new KeyValuePart();
    myArguments.add(part);
    return part;
  }

  @Override
  public void execute() throws BuildException {
    if (myName == null || myName.trim().isEmpty()) {
      throw new BuildException("'name' attribute should be defined");
    }

    if (myValue != null) {
      if (!myArguments.isEmpty()) {
        throw new BuildException("'value' attribute must not co-exist with 'param' sub-elements");
      }

      logServiceMessage(ServiceMessage.asString(myName, myValue));
    } else {

      final Map<String, String> paramz = new LinkedHashMap<String, String>();

      for (KeyValuePart arg : myArguments) {
        final String name = arg.getName();
        final String value = arg.getValue();

        if (name == null || name.trim().length() == 0) {
          throw new BuildException("Some 'param' element has no 'name' attribute");
        }

        if (arg.getSkipIfEmpty() && (value == null || value.length() == 0)) {
          continue;
        }

        if (value == null) {
          throw new BuildException("Some 'param' element has no 'value' attribute");
        }

        final String oldValue = paramz.put(name, value);
        if (oldValue != null) {
          throw new BuildException("Multiple values for <param name='" + name + "' ...");
        }
      }

      logServiceMessage(ServiceMessage.asString(myName, paramz));
    }
  }

  private void logServiceMessage(@NotNull final String message) {
    final String NL = "\r\n";
    final String text = NL + message + NL;
    //TODO: may use socket or console output to make sure it's not skipped
    getProject().log(this, text, Project.MSG_WARN);
  }

}


@@ -527,16 +527,60 @@
  Task %7B%0A
+  @Nullable private String myFlowId = null;%0A
   @Nulla
@@ -883,16 +883,163 @@
 e;%0A  %7D%0A%0A
+  @Nullable%0A  public String getFlowId() %7B%0A    return myFlowId;%0A  %7D%0A%0A  public void setFlowId(@Nullable String flowId) %7B%0A    myFlowId = flowId;%0A  %7D%0A%0A
   @NotNu
@@ -1531,32 +1531,173 @@
 nts%22);%0A      %7D%0A%0A
+      if (myFlowId != null) %7B%0A        throw new BuildException(%22flowId attribute is not supported for value only service message%22);%0A      %7D%0A%0A
       logService
@@ -1834,24 +1834,134 @@
 , String%3E();
+%0A      %0A      if (myFlowId != null && myFlowId.length() %3E 0) %7B%0A        paramz.put(%22flowId%22, myFlowId);%0A      %7D
 %0A%0A      for 

add flowId