package com.intellij.tasks.jira.soap;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tasks.*;
import com.intellij.tasks.impl.TaskUtil;
import com.intellij.tasks.jira.JiraRemoteApi;
import com.intellij.tasks.jira.JiraRepository;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import icons.TasksIcons;
import org.apache.commons.httpclient.HttpClient;
import org.apache.xmlrpc.CommonsXmlRpcTransport;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.net.URL;
import java.util.*;


/**
 * Legacy XML-RPC connector restored due to IDEA-120595.
 *
 * @author Mikhail Golubev
 */
@SuppressWarnings("UseOfObsoleteCollectionType")
public class JiraXmlRpcApi extends JiraRemoteApi {

  private static final Logger LOG = Logger.getInstance(JiraXmlRpcApi.class);
  private static final String XML_RPC_APT_PATH = "/rpc/xmlrpc";


  public JiraXmlRpcApi(@NotNull JiraRepository repository) {
    super(repository);
  }

  @SuppressWarnings("unchecked")
  private <T> T execute(@NotNull String method, @NotNull Object... args) throws Exception {
    URL url = new URL(myRepository.getUrl() + XML_RPC_APT_PATH);
    XmlRpcClient client = new XmlRpcClient(url);
    HttpClient httpClient = myRepository.getHttpClient();
    CommonsXmlRpcTransport transport = new CommonsXmlRpcTransport(url, httpClient);
    //transport.setBasicAuthentication(myRepository.getUsername(), myRepository.getPassword());
    // empty token can be added to every method parameters, if basic authorization scheme is used to login
    Vector<Object> parameters = new Vector<Object>(ContainerUtil.concat(false, Arrays.asList(args), ""));
    XmlRpcRequest request = new XmlRpcRequest("jira1." + method, parameters);
    try {
      return (T)client.execute(request, transport);
    }
    // TODO error handling
    catch (XmlRpcException e) {
      LOG.error(e);
      // extract server message
      String message = e.getMessage();
      int index = message.lastIndexOf(':');
      if (index >= 0 && index < message.length() - 1) {
        message = message.substring(index + 1);
      }
      throw new Exception(TaskBundle.message("failure.server.message", message), e);
    }
  }

  @NotNull
  @Override
  public List<Task> findTasks(String query, int max) throws Exception {
    Vector<Object> raw = execute("getIssuesFromTextSearch", StringUtil.isEmpty(query) ? "i" : query);
    List<Task> tasks = ContainerUtil.mapNotNull(raw, new Function<Object, Task>() {
      @SuppressWarnings("unchecked")
      @Override
      public Task fun(Object task) {
        return createIssue((Hashtable<String, Object>)task);
      }
    });
    return tasks.subList(0, Math.max(tasks.size(), max));
  }

  @Nullable
  @Override
  public Task findTask(String key) throws Exception {
    return createIssue(this.<Hashtable<String, Object>>execute("getIssue", key));
  }

  @Nullable
  private static Task createIssue(@Nullable final Hashtable<String, Object> map) {
    if (map == null) {
      return null;
    }
    // TODO filter by assignee?
    return new Task() {
      @NotNull
      @Override
      public String getId() {
        return (String)map.get("key");
      }

      @NotNull
      @Override
      public String getSummary() {
        return (String)map.get("summary");
      }

      @NotNull
      @Override
      public String getDescription() {
        return (String)map.get("description");
      }

      @Nullable
      @Override
      public Date getCreated() {
        return TaskUtil.parseDate((String)map.get("created"));
      }

      @Nullable
      @Override
      public Date getUpdated() {
        return TaskUtil.parseDate((String)map.get("updated"));
      }

      @NotNull
      @Override
      public Comment[] getComments() {
        // TODO
        return new Comment[0];
      }

      @NotNull
      @Override
      public Icon getIcon() {
        return TasksIcons.Jira;
      }

      @NotNull
      @Override
      public TaskType getType() {
        // TODO
        return null;
      }

      @Override
      public boolean isClosed() {
        // TODO
        return false;
      }

      @Override
      public boolean isIssue() {
        return true;
      }

      @Nullable
      @Override
      public String getIssueUrl() {
        // TODO
        return null;
      }
    };
  }

  @NotNull
  @Override
  public final ApiType getType() {
    return ApiType.XML_RPC;
  }

  @Override
  public void setTaskState(Task task, TaskState state) throws Exception {
    throw new Exception(TaskBundle.message("jira.failure.no.state.update"));
  }

  @Override
  public void updateTimeSpend(LocalTask task, String timeSpent, String comment) throws Exception {
    throw new Exception(TaskBundle.message("jira.failure.no.time.spent"));
  }
}
