package minhhai2209.jirapluginconverter.plugin.render;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.text.StrSubstitutor;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.project.ProjectManager;

public class ParameterContextBuilder {

  private static final ObjectMapper objectMapper = new ObjectMapper();

  @SuppressWarnings("unchecked")
  private static void buildContextParams(HttpServletRequest request, Map<String, String> acContext) {

    try {

      acContext.put("issue.id", "");
      acContext.put("issue.key", "");
      acContext.put("issuetype.id", "");
      acContext.put("project.id", "");
      acContext.put("project.key", "");
      acContext.put("version.id", "");
      acContext.put("component.id", "");

      Map<String, String[]> contextParams = request.getParameterMap();
      String[] productContexts = contextParams.get("product-context");
      if (productContexts != null && productContexts.length > 0) {
        String productContextAsString = productContexts[0];
        TypeReference<Map<String, String>> typeReference = new TypeReference<Map<String, String>>() {};
        Map<String, String> productContext = objectMapper.readValue(productContextAsString, typeReference);
        acContext.putAll(productContext);
      }

      ProjectManager projectManager = ComponentAccessor.getProjectManager();
      IssueManager issueManager = ComponentAccessor.getIssueManager();

      if (contextParams.containsKey("issueKey")) {
        String issueKey = contextParams.get("issueKey")[0];
        if (!issueKey.contains("$")) {
          acContext.put("issue.key", issueKey);
          MutableIssue issue = issueManager.getIssueByCurrentKey(issueKey);
          if (issue != null) {
            Project project = issue.getProjectObject();
            acContext.put("issue.id", issue.getId().toString());
            acContext.put("issuetype.id", issue.getIssueTypeId());
            acContext.put("project.id", project.getId().toString());
            acContext.put("project.key", project.getKey());
          }
        }
      }

      if (contextParams.containsKey("projectKey")) {
        String projectKey = contextParams.get("projectKey")[0];
        if (!projectKey.contains("$")) {
          acContext.put("project.key", projectKey);
          Project project = projectManager.getProjectByCurrentKey(projectKey);
          if (project != null) {
            acContext.put("project.id", project.getId().toString());
          }
        }
      }

      if (contextParams.containsKey("versionId")) {
        String versionId = contextParams.get("versionId")[0];
        if (!versionId.contains("$")) {
          acContext.put("version.id", versionId);
        }
      }

      if (contextParams.containsKey("componentId")) {
        String componentId = contextParams.get("componentId")[0];
        if (!componentId.contains("$")) {
          acContext.put("component.id", componentId);
        }
      }
    } catch (Exception e) {

    }
  }

  private static void buildContextParams(Map<String, Object> contextParams, Map<String, String> acContext) {

    Object o = contextParams.get("issue");
    if (o instanceof Issue) {
      Issue issue = (Issue) o;
      if (issue != null) {
        acContext.put("issue.key", issue.getKey());
        acContext.put("issue.id", issue.getId().toString());
        acContext.put("issuetype.id", issue.getIssueTypeId());
      }
    }

    o = contextParams.get("project");
    if (o instanceof Project) {
      Project project = (Project) o;
      if (project != null) {
        acContext.put("project.key", project.getKey());
        acContext.put("project.id", project.getId().toString());
      }
    }
  }

  private static void buildContextParams(Issue issue, Map<String, String> acContext) {

    if (issue != null) {
      acContext.put("issue.key", issue.getKey());
      acContext.put("issue.id", issue.getId().toString());
      acContext.put("issuetype.id", issue.getIssueTypeId());
    }
  }

  public static String buildUrl(String url, Map<String, String> acContext) {
    StrSubstitutor substitutor = new StrSubstitutor(acContext, "${", "}");
    url = substitutor.replace(url);
    return url;
  }

  public static Map<String, String> buildContext(
      HttpServletRequest request, Map<String, Object> contextParams, Issue issue) {
    Map<String, String> acContext = new HashMap<String, String>();
    if (request != null) {
      buildContextParams(request, acContext);
    } else if (contextParams != null) {
      buildContextParams(contextParams, acContext);
    } else if (issue != null) {
      buildContextParams(issue, acContext);
    }
    return acContext;
  }
}

@@ -53,251 +53,8 @@
 r;%0A%0A
-import java.util.HashMap;%0Aimport java.util.Map;%0A%0Aimport javax.servlet.http.HttpServletRequest;%0A%0Aimport org.apache.commons.lang.text.StrSubstitutor;%0Aimport org.codehaus.jackson.map.ObjectMapper;%0Aimport org.codehaus.jackson.type.TypeReference;%0A%0A
 impo
@@ -327,16 +327,257 @@
 Manager;
+%0Aimport org.apache.commons.lang.text.StrSubstitutor;%0Aimport org.codehaus.jackson.map.ObjectMapper;%0Aimport org.codehaus.jackson.type.TypeReference;%0A%0Aimport javax.servlet.http.HttpServletRequest;%0Aimport java.util.HashMap;%0Aimport java.util.Map;
 %0A%0Apublic
@@ -3342,25 +3342,44 @@
 eption e) %7B%0A
+      // do nothing
 %0A
-
     %7D%0A  %7D%0A%0A 
@@ -3526,24 +3526,47 @@
 t(%22issue%22);%0A
+    if (o != null) %7B%0A  
     if (o in
@@ -3579,24 +3579,26 @@
 of Issue) %7B%0A
+  
       Issue 
@@ -3620,35 +3620,8 @@
  o;%0A
-      if (issue != null) %7B%0A
     
@@ -3841,24 +3841,47 @@
 %22project%22);%0A
+    if (o != null) %7B%0A  
     if (o in
@@ -3896,24 +3896,26 @@
  Project) %7B%0A
+  
       Projec
@@ -3943,37 +3943,8 @@
  o;%0A
-      if (project != null) %7B%0A
     
@@ -4446,24 +4446,24 @@
 cContext) %7B%0A
+
     StrSubst
@@ -4515,19 +4515,8 @@
 text
-, %22$%7B%22, %22%7D%22
 );%0A 

update context params