package com.cadence.jira.cdnscfupdated.jql;
import com.atlassian.jira.bc.issue.search.SearchService;
import com.atlassian.jira.bc.issue.search.SearchService.ParseResult;
import java.lang.reflect.Method;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.user.UserProjectHistoryManager;
//import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.atlassian.jira.JiraDataType;
import com.atlassian.jira.JiraDataTypes;
import com.atlassian.jira.jql.operand.QueryLiteral;
import com.atlassian.jira.jql.query.QueryCreationContext;
import com.atlassian.jira.plugin.jql.function.AbstractJqlFunction;
import com.atlassian.jira.util.MessageSet;
import com.atlassian.query.Query;
import com.atlassian.query.clause.TerminalClause;
import com.atlassian.query.operand.FunctionOperand;
import com.atlassian.jira.issue.search.SearchException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.changehistory.ChangeHistoryItem;
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager;
import com.atlassian.jira.issue.search.SearchResults;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.jql.validator.NumberOfArgumentsValidator;
import java.util.Calendar;
//@Scanned
public class cdnsCfUpdated extends AbstractJqlFunction {
private static final Logger log = LoggerFactory.getLogger(cdnsCfUpdated.class);
@ComponentImport
private final UserProjectHistoryManager userProjectHistoryManager;
public cdnsCfUpdated(UserProjectHistoryManager userProjectHistoryManager) {
this.userProjectHistoryManager = userProjectHistoryManager;
}
MessageSet messageSet = null;
public MessageSet validate(ApplicationUser searcher, FunctionOperand operand, TerminalClause terminalClause) {
messageSet = new NumberOfArgumentsValidator(4, 4, getI18n()).validate(operand);
// messageSet = new NumberOfArgumentsValidator(NUM_OF_ARGUMENTS, NUM_OF_ARGUMENTS, getI18n()).validate(functionOperand);
String date = operand.getArgs().get(2);
String char1 = null;
String char2_c = null;
int char2 = 0;
char1 = date.substring(0,1);
if(date.contains("-") && (date.contains("d") || date.contains("w") || date.contains("y") || date.contains("M"))) {
char2_c = null;
if(date.contains("d")) {
char2_c = date.substring(1,date.indexOf('d'));
} else if(date.contains("y")){
char2_c = date.substring(1,date.indexOf('y'));
}else if(date.contains("M")){
char2_c = date.substring(1,date.indexOf('M'));
}else if(date.contains("w")){
char2_c = date.substring(1,date.indexOf('w'));
}
char2 = Integer.parseInt(char2_c);
}
String char3 = date.substring(date.length() - 1);
if (!(date.contains("-") || (char1.equals("-") && char3.equals("d")) || (char1.equals("-") && char3.equals("y")) || (char1.equals("-") && char3.equals("M")) || (char1.equals("-") && char3.equals("w")) || date.equals("now()") || date.equals("startOfDay()") || date.equals("startOfWeek()") || date.equals("startOfMonth()") || date.equals("startOfYear()") || date.equals("endOfDay()") || date.equals("endOfWeek()") || date.equals("endOfMonth()") || date.equals("endOfYear()"))) {
messageSet.addErrorMessage("Date value '"+date+"' for function 'cdnsCfUpdated' is invalid. Valid formats include: 'yyyy-MM-dd' or date functions like: 'now()','startOfDay()', 'startOfWeek()', 'startOfMonth()', 'startOfYear()', 'endOfDay()', 'endOfWeek()', 'endOfMonth()', 'endOfYear()' or (-)nn( y | M | w | d )");
return messageSet;
}
SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd");
simpleDateFormat.setLenient(false);
Date escalationDateTime;
try {
if (date.contains("-") && date.contains(":")) {
String[] dateTime = StringUtils.split(date,' ');
String tempDate = dateTime[0];
String tempTime = dateTime[1];
String[] timeArray = StringUtils.split(tempTime,':');
int tempHour = Integer.parseInt(timeArray[0]);
int tempMin = Integer.parseInt(timeArray[1]);
if (tempHour < 0 || tempHour > 23 || tempMin < 0 || tempMin > 59) {
messageSet.addErrorMessage("Date value :'"+date+"' is invalid.");
return messageSet;
}else {
escalationDateTime = simpleDateFormat.parse(tempDate);
}
}
else if (date.contains("-") && !date.contains("d") && !date.contains("w") && !date.contains("y") && !date.contains("M")) {
escalationDateTime = simpleDateFormat.parse(date);
}
} catch (ParseException e1) {
messageSet.addErrorMessage("Date value '"+date+"' is invalid.");
return messageSet;
}
String operator = operand.getArgs().get(1);
if (!(operator.equals(">") || operator.equals("<") || operator.equals(">=") || operator.equals("<=") || operator.equals("="))) {
messageSet.addErrorMessage("Operator must be any of >, <, >=, <=, =");
return messageSet;
}
if (messageSet.hasAnyErrors()) {
return messageSet;
}
messageSet = null;
//return this.validateNumberOfArgs(functionOperand, NUM_OF_ARGUMENTS);
//System.out.println("111111 "+customField);
return validateNumberOfArgs(operand, 4);
}
public List<QueryLiteral> getValues(QueryCreationContext queryCreationContext, FunctionOperand operand, TerminalClause terminalClause) {
final List<QueryLiteral> literals = new LinkedList<>();
final List<String> arguments = operand.getArgs();
final String customField = arguments.get(0);
final String operator = arguments.get(1);
final String date = arguments.get(2);
final String query = arguments.get(3);
//System.out.println("Project :::: " + projectName);
String char1 = null;
String char2_c = null;
int char2 = 0;
String char3 = null;
//System.out.println("22222 "+customField);
//int l = date.length();
//System.out.println("Date length l : " + l);
List<QueryLiteral> values = new ArrayList<>();
if (messageSet == null) {
try {
char1 = date.substring(0,1);
if(date.contains("-") && (date.contains("d") || date.contains("w") || date.contains("y") || date.contains("M"))) {
if(date.contains("d")) {
char2_c = date.substring(1,date.indexOf('d'));
} else if(date.contains("y")){
char2_c = date.substring(1,date.indexOf('y'));
}else if(date.contains("M")){
char2_c = date.substring(1,date.indexOf('M'));
}else if(date.contains("w")){
char2_c = date.substring(1,date.indexOf('w'));
}
char2 = Integer.parseInt(char2_c);
//System.out.println("Char1 ::: " + char1 + " Char2 ::: " + char2 + " Char3 ::: "+ char3);
}
char3 = date.substring(date.length() - 1);
if (!(date.contains(":") || char3.equals("d") || char3.equals("y") || char3.equals("M") || char3.equals("w") || date.equals("now()") || date.equals("startOfDay()") || date.equals("startOfWeek()") || date.equals("startOfMonth()") || date.equals("startOfYear()") || date.equals("endOfDay()") || date.equals("endOfWeek()") || date.equals("endOfMonth()") || date.equals("endOfYear()"))) {
// date = date + " 00:00";
}
Date nowDateTime = new Date();
System.out.println("Current Date :::" + nowDateTime);
SimpleDateFormat simpleDateTimeFormat =new SimpleDateFormat("yyyy-MM-dd hh:mm");
SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd");
String startTempDate = simpleDateFormat.format(nowDateTime);
String endTempDate = startTempDate;
String tempDateTime = simpleDateTimeFormat.format(nowDateTime);
Date startDateDay = new Date();
String strDate_day = null;
String strDate_mon = null;
String strDate_Yr = null;
String strDate_Wk = null;
//System.out.println("Current Date My code :::" + startDateDay);
if(char1.equals("-") && char3.equals("d")) {
startDateDay.setDate(startDateDay.getDate() - char2);
strDate_day = simpleDateFormat.format(startDateDay);
} else if(char1.equals("-") && char3.equals("M")) {
startDateDay.setMonth(startDateDay.getMonth() - char2);
strDate_mon = simpleDateFormat.format(startDateDay);
} else if(char1.equals("-") && char3.equals("y")) {
startDateDay.setYear(startDateDay.getYear() - char2);
strDate_Yr = simpleDateFormat.format(startDateDay);
} else if(char1.equals("-") && char3.equals("w")) {
startDateDay.setDate(startDateDay.getDate() - 7*char2);
strDate_Wk = simpleDateFormat.format(startDateDay);
}
Date escalationDateTime = new Date();
Calendar cal = Calendar.getInstance();
int year=cal.get(Calendar.YEAR);
int month=cal.get(Calendar.MONTH);
cal.set(year, 0, 1);
Date firstdate=cal.getTime();//first day of an year
String startFirstdate = simpleDateFormat.format(firstdate);
//startFirstdate = startFirstdate + " 00:00";
cal.set(year,11,31);
Date enddate=cal.getTime();//last day of an year
cal.set(year, month, 1);
Date startOfMonth=cal.getTime();//first day a month
String startstartOfMonth = simpleDateFormat.format(startOfMonth);
String endEnddate = simpleDateFormat.format(enddate);
//endEnddate = endEnddate + " 23:59";
cal = Calendar.getInstance();
int daysQty = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(year, month, daysQty);
Date endOfMonth=cal.getTime();//last day of a month
String endEndOfMonth = simpleDateFormat.format(endOfMonth);
//endEndOfMonth = endEndOfMonth + " 23:59";
int dayNm = escalationDateTime.getDay();
int firstDay = -dayNm;
int endDay = dayNm;
cal = Calendar.getInstance();
cal.add(Calendar.DATE, firstDay);
cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_WEEK,(cal.getActualMinimum(Calendar.DAY_OF_WEEK)+1));
Date startOfWeek = cal.getTime();//first day a week
String startStartOfWeek = simpleDateFormat.format(startOfWeek);
//startStartOfWeek = startStartOfWeek + " 00:00";
cal.set(Calendar.DAY_OF_WEEK,(cal.getActualMaximum(Calendar.DAY_OF_WEEK)-1));
Date endOfWeek = cal.getTime();//last day a week
String endEndOfWeek = simpleDateFormat.format(endOfWeek);
//endEndOfWeek = endEndOfWeek + " 23:59";
if (!(date.equals("now()") || char3.equals("d") || char3.equals("y") || char3.equals("M") || char3.equals("w") || date.equals("startOfDay()") || date.equals("startOfWeek()") || date.equals("startOfMonth()") || date.equals("startOfYear()") || date.equals("endOfDay()") || date.equals("endOfWeek()") || date.equals("endOfMonth()") || date.equals("endOfYear()"))) {
if (date.contains(":")){
escalationDateTime = simpleDateTimeFormat.parse(date);
}else {
escalationDateTime = simpleDateFormat.parse(date);
}
}
List<Long> searchParamIssueIds = null;
//IssueEscalation[] escalatedIssues;
if (date.equals("now()"))
{
searchParamIssueIds = getIssuesIdByJQL(customField, operator, startTempDate,date,query);
}
else if (date.equals("startOfWeek()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, startStartOfWeek,date,query);
}
else if (date.equals("startOfDay()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, startTempDate,date,query);
}
else if (date.equals("startOfMonth()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, startstartOfMonth,date,query);
}
else if (date.equals("startOfYear()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, startFirstdate,date,query);
}
else if (date.equals("endOfMonth()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, endEndOfMonth,date,query);
}
else if (date.equals("endOfWeek()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, endEndOfWeek,date,query);
}
else if (date.equals("endOfDay()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, endTempDate,date,query);
}
else if (date.equals("endOfYear()")) {
searchParamIssueIds = getIssuesIdByJQL(customField, operator, endEnddate,date,query);
}
else if(char3.equals("d") ){
searchParamIssueIds = getIssuesIdByJQL(customField, operator, strDate_day,date,query);
}
else if(char3.equals("M") ){
searchParamIssueIds = getIssuesIdByJQL(customField, operator, strDate_mon,date,query);
}
else if(char3.equals("y") ){
searchParamIssueIds = getIssuesIdByJQL(customField, operator, strDate_Yr ,date,query);
}
else if(char3.equals("w") ){
searchParamIssueIds = getIssuesIdByJQL(customField, operator, strDate_Wk ,date,query);
}
else
{
searchParamIssueIds = getIssuesIdByJQL(customField, operator, date,date,query);
}
for(Long userHistoryItem : searchParamIssueIds) {
final String value = userHistoryItem.toString();
try {
literals.add(new QueryLiteral(operand, Long.parseLong(value)));
} catch (NumberFormatException e) {
// log.warn(String.format("User history returned a non numeric project IS '%s'.", value));
} }
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return literals;
}
public int getMinimumNumberOfExpectedArguments() {
return 0;
}
public JiraDataType getDataType() {
return JiraDataTypes.ISSUE;
}
private static List<Long> getIssuesIdByJQL(String customField, String operatorPassed, String passedDate, String action, String query1) {
//final String jql="project = \"OKTA\" and createdDate >= \"2010/10/01\" and issue != \"OKTA-3\"";
final String jql;
//System.out.println("33333 passed dateeeeeeeeeee"+passedDate);
String passedStartDateTime = passedDate+" 00:00";
String passedEndDateTime = passedDate+" 23:59";
System.out.println(" JQL : " + query1);
if (action.equals("endOfDay()") || action.equals("endOfWeek()") || action.equals("endOfMonth()") || action.equals("endOfYear()"))
{
passedStartDateTime = passedDate+" 23:59";
}
if (action.contains("startOf") && operatorPassed.equals(">")){
jql= query1 + " and (createdDate > '"+passedStartDateTime+"' or updatedDate > '"+passedStartDateTime+"')";
}
else if (action.contains("startOf") && operatorPassed.equals(">")){
jql= query1 + " and (createdDate > '"+passedEndDateTime+"' or updatedDate > '"+passedEndDateTime+"')";
}else if (action.contains("startOf") && operatorPassed.equals(">=")){
jql= query1 + " and (createdDate >= '"+passedStartDateTime+"' or updatedDate >= '"+passedStartDateTime+"')";
}else if(action.contains("startOf") && operatorPassed.equals("<")){
jql= query1 + " and (createdDate < '"+passedStartDateTime+"' or updatedDate < '"+passedStartDateTime+"')";
}else if(action.contains("startOf") && operatorPassed.equals("<=")){
jql= query1 + " and (createdDate <= '"+passedEndDateTime+"' or updatedDate <= '"+passedEndDateTime+"')";
}else if((action.contains("-") && (action.contains("d") || action.contains("y") || action.contains("w") || action.contains("M"))) && operatorPassed.equals(">")){
jql= query1 + " and (createdDate > '"+passedStartDateTime+"' or updatedDate > '"+passedStartDateTime+"')";
}else if((action.contains("-") && (action.contains("d") || action.contains("y") || action.contains("w") || action.contains("M"))) && operatorPassed.equals(">")){
//jql="(project = \"" + project_name + "\") and (createdDate > '"+passedEndDateTime+"' or updatedDate > '"+passedEndDateTime+"')";
jql= query1 + " and (createdDate > '"+passedEndDateTime+"' or updatedDate > '"+passedEndDateTime+"')";
}else if((action.contains("-") && (action.contains("d") || action.contains("y") || action.contains("w") || action.contains("M"))) && operatorPassed.equals(">=")){
jql= query1 + " and (createdDate >= '"+passedStartDateTime+"' or updatedDate >= '"+passedStartDateTime+"')";
}else if((action.contains("-") && (action.contains("d") || action.contains("y") || action.contains("w") || action.contains("M"))) && operatorPassed.equals("<")){
jql= query1 + " and (createdDate < '"+passedStartDateTime+"' or updatedDate < '"+passedStartDateTime+"')";
}else if((action.contains("-") && (action.contains("d") || action.contains("y") || action.contains("w") || action.contains("M"))) && operatorPassed.equals("<=")){
jql= query1 + " and (createdDate <= '"+passedEndDateTime+"' or updatedDate <= '"+passedEndDateTime+"')";
}
else{
jql= query1 + " and ((createdDate >= '"+passedStartDateTime+"') or (updatedDate >= '"+passedStartDateTime+"'))";
//jql = "(project = \"" + query1 + "\") and ((createdDate >= '"+passedStartDateTime+"') or (updatedDate >= '"+passedStartDateTime+"'))";
}
System.out.println("33333 "+jql);
JiraAuthenticationContext authenticationContext = ComponentAccessor.getJiraAuthenticationContext();
ApplicationUser loggedInUser = authenticationContext.getLoggedInUser();
List<Long> issuesKeys = new ArrayList<>();
SearchService searchService = ComponentAccessor.getComponentOfType(SearchService.class);
ParseResult parseResult = searchService.parseQuery(loggedInUser, jql);
if (parseResult.isValid()) {
Query query = searchService.parseQuery(loggedInUser, jql).getQuery();
List<Issue> issues = null;
try {
SearchResults<Issue> searchResults = searchService.search(loggedInUser, query, PagerFilter.getUnlimitedFilter());
try {
Method newGetMethod = null;
try {
newGetMethod = SearchResults.class.getMethod("getIssues");
} catch (NoSuchMethodException e) {
System.out.println("Catch on linme 406" + e);
try {
newGetMethod = SearchResults.class.getMethod("getResults");
} catch (NoSuchMethodError e2) {
System.out.println("Catch on linme 411" + e2);
}
}
if (newGetMethod != null) {
try {
System.out.println("Inside try of newGetMethod Invoke");
issues = (List<Issue>) newGetMethod.invoke(searchResults); //here is the call to invole searchResults
} catch (Exception einvoke) {
System.out.println("Exception in method invoke" + einvoke);
}
} else {
System.out.println("Catch on line 424");
throw new RuntimeException("ICT: SearchResults Service from JIRA NOT AVAILABLE (getIssue / getResults)");
}
} catch (Exception e) {
System.out.println("Catch on linme 430" + e);
}
} catch (SearchException e) {
System.out.println("Catch on linme 433" + e);
log.error(e.getMessage(), e);
}
for (Issue issue : issues) {
//issuesKeys.add(issue.getId());
//System.out.println("44444 "+issue);
ChangeHistoryManager changeHistoryManager = ComponentAccessor.getChangeHistoryManager();
List<ChangeHistoryItem> items = changeHistoryManager.getAllChangeItems(issue);
for (ChangeHistoryItem item : items) {
String field = item.getField();
Timestamp historyDate = item.getCreated();
String S = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(historyDate);
String[] parts = S.split(" ");
//System.out.println(operatorPassed + "History Date--------:" + parts[0]);
//System.out.println("Passed date--------:" + passedDate);
Date historyDateObj = null;
try {
historyDateObj = new SimpleDateFormat("yyyy-MM-dd").parse(parts[0].toString());
} catch (ParseException e) {
e.printStackTrace();
}
Date passedDateObj = null;
try {
passedDateObj = new SimpleDateFormat("yyyy-MM-dd").parse(passedDate.toString());
} catch (ParseException e) {
e.printStackTrace();
}
if (field.equals(customField))
{
if (operatorPassed.equals(">")){
if(historyDateObj.compareTo(passedDateObj) > 0) {
System.out.println("Date history occurs after Date passed");
issuesKeys.add(issue.getId());
}
}
if (operatorPassed.equals("<")){
if(historyDateObj.compareTo(passedDateObj) < 0) {
System.out.println("Date history occurs before Date passed");
issuesKeys.add(issue.getId());
}
}
if (operatorPassed.equals("=")){
if(historyDateObj.compareTo(passedDateObj) == 0) {
System.out.println("Both dates are equal");
issuesKeys.add(issue.getId());
}
}
if (operatorPassed.equals(">=")){
if(historyDateObj.compareTo(passedDateObj) == 0) {
//System.out.println("Both dates are equal 1");
issuesKeys.add(issue.getId());
}
if(historyDateObj.compareTo(passedDateObj) > 0) {
//System.out.println("Date history occurs after Date passed 1");
issuesKeys.add(issue.getId());
}
}
if (operatorPassed.equals("<=")){
if(historyDateObj.compareTo(passedDateObj) == 0) {
//System.out.println("Both dates are equal 2");
issuesKeys.add(issue.getId());
}
if(historyDateObj.compareTo(passedDateObj) < 0) {
//System.out.println("Date history occurs after Date passed 2");
issuesKeys.add(issue.getId());
}
}
}
}
}
} else {
// throw new JqlParseException(null, parseResult.getErrors().toString());
}
return issuesKeys;
}
}