import org.apache.log4j.Logger
import org.apache.log4j.Level
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLinkTypeManager
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.security.groups.GroupManager
log.setLevel(Level.INFO)
log.info("SCRIPT - START")
log.info("-----------------------------------------")
def pluginAccessor = ComponentAccessor.getPluginAccessor();
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService)
def user = ComponentAccessor.getJiraAuthenticationContext().getUser()
// -----------------------------------------------------
// TO EDIT: please write a valid JQL query returning the issues to be updated
def jqlQuery = "project = PM"
// TO EDIT: Please populate the table with the following information:
// - In the 1st column, the Connect field ID to be copied (source)
// - In the 2nd column, the Text Area field ID to be populated (target)
// This must be a 1 to 1 relationship, and one Connect field must correspond to one Text Area field.
def fieldsMapping =
    [
        ['customfield_10200','customfield_10305'],
        ['customfield_10302','customfield_10306'],
        ['customfield_10203','customfield_10307'],
        ['customfield_10303','customfield_10308'],
        ['customfield_10304','customfield_10309'],
    ]
// Loop to browse all Connect fields to be copied.
for(fields in fieldsMapping){
    def connectFieldId = fields[0]
    log.info("SCRIPT - Connect field ID => "+connectFieldId)
    def textFieldId = fields[1]
    def textField = customFieldManager.getCustomFieldObject(textFieldId);
    // We get the Connect field type (Live Text, Live User, Snapshot Text, Snapshot Date or Snapshot Datetime)
    def connectFieldType = customFieldManager.getCustomFieldObject(connectFieldId).getCustomFieldType().getName();
    log.info("SCRIPT - Connect field type => "+customFieldManager.getCustomFieldObject(connectFieldId).getCustomFieldType().getName())
    // Improvement of the JQL query with a check of the Connect field in each ticket
    def jqlQueryOptimized;
    if(jqlQuery){
        jqlQueryOptimized = jqlQuery+" AND cf["+connectFieldId.replace('customfield_','')+"] IS NOT EMPTY"
    }
    else{
        jqlQueryOptimized = "cf["+connectFieldId.replace('customfield_','')+"] IS NOT EMPTY"
    }
    log.info("SCRIPT - JQL Query => "+jqlQueryOptimized)
    // Processing of the JQL query
    def results = searchService.search(user, jqlQueryParser.parseQuery(jqlQueryOptimized), PagerFilter.getUnlimitedFilter())
    def issueManager = ComponentAccessor.issueManager
    def issueLinkTypeManager = ComponentAccessor.getComponent(IssueLinkTypeManager)
    final Long sequence = 1L
    def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
    log.info("SCRIPT - Total issues to be updated => ${results.total}")
    // Different value copy actions are performed depending on the Connect field type
    if(connectFieldType == "Elements Connect - Live - Text"){    
        // We get the classes related to the Elements Connect API
        def plugin = pluginAccessor.getPlugin("com.valiantys.jira.plugins.SQLFeed");
        def serviceClass = plugin.getClassLoader().loadClass("com.valiantys.nfeed.api.IFieldDisplayService");
        def fieldDisplayService = ComponentAccessor.getOSGiComponentInstanceOfType(serviceClass);
        // Loop  to browse all the issues returned by the JQL Query
        results.getResults().eachWithIndex { issue , it ->
            String displayValue = "";
            Object displayResult = fieldDisplayService.getDisplayResult(issue.key, connectFieldId);
            if (displayResult && displayResult.getDisplay()) {
                def textValues = displayResult.getDisplay().replace('<BR/>','\n');
                // We copy the Connect field value to the Text Area field
                textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), textValues), new DefaultIssueChangeHolder())  
                log.info("SCRIPT - issue ${issue.key} has been updated ("+(it+1)+" out of ${results.total})");
            }    
        }
    }
    else if(connectFieldType == "Elements Connect - Live - User") {
        // We get the classes related to the Elements Connect API
        def plugin = pluginAccessor.getPlugin("com.valiantys.jira.plugins.SQLFeed");
        def serviceClass = plugin.getClassLoader().loadClass("com.valiantys.nfeed.api.IFieldValueService");
        def fieldValueService = ComponentAccessor.getOSGiComponentInstanceOfType(serviceClass);
        // Loop  to browse all the issues returned by the JQL Query
        results.getResults().eachWithIndex { issue , it ->
            def userValues = fieldValueService.getFieldValues(issue.key, connectFieldId);
            if(userValues){
                // We copy the Connect field value to the Text Area field
                textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), userValues.join('\n')), new DefaultIssueChangeHolder())
                log.info("SCRIPT - issue "+issue.key+" has been updated ("+(it+1)+" out of ${results.total})");
            }
        }
    }
    else if(connectFieldType == "Elements Connect - Snapshot - Text" || connectFieldType == "Elements Connect - Snapshot - Datetime") {
        // Loop  to browse all the issues returned by the JQL Query
        results.getResults().eachWithIndex { issue , it ->
            def snapshotField = customFieldManager.getCustomFieldObject(connectFieldId)
            def snapshotValues = issue.getCustomFieldValue(snapshotField)
            if(snapshotValues){
                // We copy the Connect field value to the Text Area field
                textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), snapshotValues.toString()), new DefaultIssueChangeHolder())
                log.info("SCRIPT - issue "+issue.key+" has been updated ("+(it+1)+" out of ${results.total})");
            }
        }
    }
    else if(connectFieldType == "Elements Connect - Snapshot - Date") {
        // Loop  to browse all the issues returned by the JQL Query
        results.getResults().eachWithIndex { issue , it ->
            def snapshotField = customFieldManager.getCustomFieldObject(connectFieldId)
            def snapshotValues = issue.getCustomFieldValue(snapshotField)
            if(snapshotValues){
                // We copy the Connect field value to the Text Area field               
                textField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textField), snapshotValues.toString().split(" ")[0]), new DefaultIssueChangeHolder())
                log.info("SCRIPT - issue "+issue.key+" has been updated ("+(it+1)+" out of ${results.total})");
            }
        }
    }
    else {
        log.info("SCRIPT - Connect Field Type => Unknown")
    }
    log.info("-----------------------------------------")
}
log.info("SCRIPT - END")