package com.intellij.tasks.redmine;

import com.google.gson.Gson;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tasks.Task;
import com.intellij.tasks.impl.RequestFailedException;
import com.intellij.tasks.impl.gson.GsonUtil;
import com.intellij.tasks.impl.httpclient.NewBaseRepositoryImpl;
import com.intellij.tasks.redmine.model.RedmineIssue;
import com.intellij.tasks.redmine.model.RedmineProject;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.Tag;
import com.intellij.util.xmlb.annotations.Transient;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

import static com.intellij.tasks.impl.httpclient.ResponseUtil.GsonSingleObjectDeserializer;
import static com.intellij.tasks.redmine.model.RedmineResponseWrapper.*;

/**
 * @author Mikhail Golubev
 * @author Dennis.Ushakov
 */
@Tag("Redmine")
public class RedmineRepository extends NewBaseRepositoryImpl {
  private static final Logger LOG = Logger.getInstance(RedmineRepository.class);
  private static final Gson GSON = GsonUtil.createDefaultBuilder().create();

  private static final Pattern ID_PATTERN = Pattern.compile("\\d+");

  public static final RedmineProject UNSPECIFIED_PROJECT = new RedmineProject() {
    @NotNull
    @Override
    public String getName() {
      return "-- from all projects --";
    }

    @Nullable
    @Override
    public String getIdentifier() {
      return getName();
    }

    @Override
    public int getId() {
      return -1;
    }
  };

  private String myAPIKey = "";
  private RedmineProject myCurrentProject;
  private List<RedmineProject> myProjects = null;

  /**
   * Serialization constructor
   */
  @SuppressWarnings({"UnusedDeclaration"})
  public RedmineRepository() {
    // empty
  }

  /**
   * Normal instantiation constructor
   */
  public RedmineRepository(RedmineRepositoryType type) {
    super(type);
    setUseHttpAuthentication(true);
  }


  /**
   * Cloning constructor
   */
  public RedmineRepository(RedmineRepository other) {
    super(other);
    setAPIKey(other.myAPIKey);
    setCurrentProject(other.getCurrentProject());
  }

  @Override
  public boolean equals(Object o) {
    if (!super.equals(o)) return false;
    if (!(o instanceof RedmineRepository)) return false;
    RedmineRepository that = (RedmineRepository)o;
    if (!Comparing.equal(getAPIKey(), that.getAPIKey())) return false;
    if (!Comparing.equal(getCurrentProject(), that.getCurrentProject())) return false;
    return true;
  }

  @NotNull
  @Override
  public RedmineRepository clone() {
    return new RedmineRepository(this);
  }

  @Nullable
  @Override
  public CancellableConnection createCancellableConnection() {
    return new NewBaseRepositoryImpl.HttpTestConnection(new HttpGet()) {
      @Override
      protected void test() throws Exception {
        // Strangely, Redmine doesn't return 401 or 403 error codes, if client sent wrong credentials, and instead
        // merely returns empty array of issues with status code of 200. This means that we should attempt to fetch
        // something more specific than issues to test proper configuration, e.g. current user information at
        // /users/current.json. Unfortunately this endpoint may be unavailable on some old servers (see IDEA-122845)
        // and in this case we have to come back to requesting issues in this case to test anything at all.

        URIBuilder uriBuilder = new URIBuilder(getRestApiUrl("users", "current.json"));
        if (isUseApiKeyAuthentication()) {
          uriBuilder.addParameter("key", getAPIKey());
        }
        myCurrentRequest.setURI(uriBuilder.build());
        HttpClient client = getHttpClient();

        HttpResponse httpResponse = client.execute(myCurrentRequest);
        StatusLine statusLine = httpResponse.getStatusLine();
        if (statusLine != null && statusLine.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
          myCurrentRequest = new HttpGet(getIssuesUrl(0, 1, true));
          statusLine = client.execute(myCurrentRequest).getStatusLine();
        }
        if (statusLine != null && statusLine.getStatusCode() != HttpStatus.SC_OK) {
          throw RequestFailedException.forStatusCode(statusLine.getStatusCode(), statusLine.getReasonPhrase());
        }
      }
    };
  }

  @Override
  public Task[] getIssues(@Nullable String query, int offset, int limit, boolean withClosed) throws Exception {
    List<RedmineIssue> issues = fetchIssues(query, offset, limit, withClosed);
    return ContainerUtil.map2Array(issues, RedmineTask.class, new Function<RedmineIssue, RedmineTask>() {
      @Override
      public RedmineTask fun(RedmineIssue issue) {
        return new RedmineTask(RedmineRepository.this, issue);
      }
    });
  }

  public List<RedmineIssue> fetchIssues(String query, int offset, int limit, boolean withClosed) throws Exception {
    ensureProjectsDiscovered();
    // Legacy API, can't find proper documentation
    //if (StringUtil.isNotEmpty(query)) {
    //  builder.addParameter("fields[]", "subject").addParameter("operators[subject]", "~").addParameter("values[subject][]", query);
    //}
    // If project was not chosen, all available issues still fetched. Such behavior may seems strange to user.
    //if (myCurrentProject != null && myCurrentProject != UNSPECIFIED_PROJECT) {
    //  builder.addParameter("project_id", String.valueOf(myCurrentProject.getId()));
    //}
    HttpClient client = getHttpClient();
    HttpGet method = new HttpGet(getIssuesUrl(offset, limit, withClosed));
    IssuesWrapper wrapper = client.execute(method, new GsonSingleObjectDeserializer<IssuesWrapper>(GSON, IssuesWrapper.class));
    return wrapper == null ? Collections.<RedmineIssue>emptyList() : wrapper.getIssues();
  }

  private URI getIssuesUrl(int offset, int limit, boolean withClosed) throws URISyntaxException {
    URIBuilder builder = new URIBuilder(getRestApiUrl("issues.json"))
      .addParameter("offset", String.valueOf(offset))
      .addParameter("limit", String.valueOf(limit))
      .addParameter("status_id", withClosed ? "*" : "open")
      .addParameter("assigned_to_id", "me");
    if (isUseApiKeyAuthentication()) {
      builder.addParameter("key", myAPIKey);
    }
    return builder.build();
  }

  public List<RedmineProject> fetchProjects() throws Exception {
    HttpClient client = getHttpClient();
    // Download projects with pagination (IDEA-125056, IDEA-125157)
    List<RedmineProject> allProjects = new ArrayList<RedmineProject>();
    int offset = 0;
    ProjectsWrapper wrapper;
    do {
      URIBuilder builder = new URIBuilder(getRestApiUrl("projects.json"));
      builder.addParameter("offset", String.valueOf(offset));
      builder.addParameter("limit", "50");
      if (isUseApiKeyAuthentication()) {
        builder.addParameter("key", myAPIKey);
      }

      HttpGet method = new HttpGet(builder.toString());
      wrapper = client.execute(method, new GsonSingleObjectDeserializer<ProjectsWrapper>(GSON, ProjectsWrapper.class));
      offset += wrapper.getProjects().size();
      allProjects.addAll(wrapper.getProjects());
    }
    while (wrapper.getTotalCount() > allProjects.size() || wrapper.getProjects().isEmpty());

    myProjects = allProjects;
    return Collections.unmodifiableList(myProjects);
  }

  @Nullable
  @Override
  public Task findTask(@NotNull String id) throws Exception {
    ensureProjectsDiscovered();
    HttpGet method = new HttpGet(getRestApiUrl("issues", id + ".json"));
    IssueWrapper wrapper = getHttpClient().execute(method, new GsonSingleObjectDeserializer<IssueWrapper>(GSON, IssueWrapper.class, true));
    if (wrapper == null) {
      return null;
    }
    return new RedmineTask(this, wrapper.getIssue());
  }

  public String getAPIKey() {
    return myAPIKey;
  }

  public void setAPIKey(String APIKey) {
    myAPIKey = APIKey;
  }

  private boolean isUseApiKeyAuthentication() {
    return !isUseHttpAuthentication() && StringUtil.isNotEmpty(myAPIKey);
  }

  @Override
  public String getPresentableName() {
    String name = super.getPresentableName();
    if (myCurrentProject != null && myCurrentProject != UNSPECIFIED_PROJECT) {
      name += "/projects/" + myCurrentProject.getIdentifier();
    }
    return name;
  }

  @Override
  public boolean isConfigured() {
    if (!super.isConfigured()) return false;
    if (isUseHttpAuthentication()) {
      return StringUtil.isNotEmpty(myPassword) && StringUtil.isNotEmpty(myUsername);
    }
    return StringUtil.isNotEmpty(myAPIKey);
  }

  @Nullable
  @Override
  public String extractId(@NotNull String taskName) {
    return ID_PATTERN.matcher(taskName).matches() ? taskName : null;
  }

  @Override
  protected int getFeatures() {
    return super.getFeatures() & ~NATIVE_SEARCH | BASIC_HTTP_AUTHORIZATION;
  }

  @Nullable
  public RedmineProject getCurrentProject() {
    return myCurrentProject;
  }

  public void setCurrentProject(@Nullable RedmineProject project) {
    myCurrentProject = project != null && project.getId() == -1 ? UNSPECIFIED_PROJECT : project;
  }

  @NotNull
  public List<RedmineProject> getProjects() {
    try {
      ensureProjectsDiscovered();
    }
    catch (Exception ignored) {
      return Collections.emptyList();
    }
    return Collections.unmodifiableList(myProjects);
  }

  private void ensureProjectsDiscovered() throws Exception {
    if (myProjects == null) {
      fetchProjects();
    }
  }

  @TestOnly
  @Transient
  public void setProjects(@NotNull List<RedmineProject> projects) {
    myProjects = projects;
  }
}
