#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
from jira.client import JIRA
from jira.config import get_jira
from jira.utils import json_loads
from pprint import pprint
from terminaltables.other_tables import UnixTable
from colorclass import Color
import os
import subprocess
import json
import sys
import warnings
from core.util import Colors
try:
    import configparser
except:
    from six.moves import configparser
class MyJira:
    # return profile section by issue url (ex - hlm, clm, hlmdev)
    def getProfileIDFromUrl(self, issue_url):
        def findfile(path):
            paths = ['.', os.path.expanduser('~')]
            paths.extend(sys.path)
            for dirname in paths:
                possible = os.path.abspath(os.path.join(dirname, path))
                if os.path.isfile(possible):
                    return possible
            return None
        config = configparser.ConfigParser(defaults={'user':None, 'pass': None, 'appid': None, 'autofix': False, 'verify': 'yes'})
        config_file = findfile('config.ini')
        if not config_file:
             raise EnvironmentError('%s was not able to locate the config.ini file in current directory, user home directory or PYTHONPATH.' % __name__)
        config.read(config_file)
        if not issue_url.startswith('http://'):
            raise EnvironmentError('You must input url started with http://')
        profile_id=None
        for section in config.sections():
            if issue_url.startswith(config.get(section, 'url')):
                profile_id=section
                break
        if not profile_id:
            raise EnvironmentError('Can not know profile id')
        return profile_id

    # return issue id extracted from issue url
    def getIssueID(self, issue_url):
        return issue_url[issue_url.rfind('/')+1:]

    # return jira object from issue url
    def getJiraFromURL(self, issue_url):
        profile_id=self.getProfileIDFromUrl(issue_url)
        jira=get_jira(profile=profile_id)
        return jira
    # return jira object & issue id from issue url
    def getJiraAndIssueFromURL(self, issue_url):
        jira=self.getJiraFromURL(issue_url)
        issue_id=self.getIssueID(issue_url)
        issue=jira.issue(issue_id)
        return jira, issue
    # return jira object & issue by issue id
    def getJiraAndIssueFromID(self, issue_id):
        profile = ['hlmdev', 'hlm']
        for id in profile:
            jira = get_jira(id)
            try:
                issue=jira.issue(issue_id)
                return jira, issue
            except:
                e = sys.exc_info()[0]
                print(e.message)
    # return project key from project name
    def getProjectKey(self, jira, projectName):
        for project in jira.projects():
            name=project.name.encode('ascii','ignore')
            if name == projectName: #'webOS Commercial Display':
                return project.key
        return None
    # return status id of status name
    def findStatusID(self, jira, status):
        status_lower = status.lower()
        for st in jira.statuses():
            if st.name.lower() == status_lower:
                return st.id
        return -1
    # return resolution id of resolution name
    def findResolutionID(self, jira, resolution):
        resolution_lower = resolution.lower()
        for rt in jira.resolutions():
            if rt.name.lower() == resolution_lower:
                return rt.id
        return -1
    # return field id from field name
    def customFieldId(self, jira, issue, find_name):
        if sys.version_info.major >= 3:
            return None
        jira_fieldId_set = set([ field[u'id'].encode('UTF-8','ignore') for field in jira.fields() ])
        issue_fieldId_set = set([ field.encode('UTF-8','ignore') for field in dir(issue.fields()) ])
        fieldId_set = jira_fieldId_set & issue_fieldId_set

        for field in jira.fields():
            field_name = field[u'name'].encode('UTF-8','ignore')
            if field[u'id'] in fieldId_set and field_name == find_name:
                if getattr(issue.fields, field['id']) != None:
                    return field['id']
        return None
    # return field value from field name
    def customFieldValue(self, jira, issue, find_name):
        if sys.version_info.major >= 3:
            return None
        jira_fieldId_set = set([ field[u'id'].encode('UTF-8','ignore') for field in jira.fields() ])
        issue_fieldId_set = set([ field.encode('UTF-8','ignore') for field in dir(issue.fields()) ])
        fieldId_set = jira_fieldId_set & issue_fieldId_set

        for field in jira.fields():
            field_name = field[u'name'].encode('UTF-8','ignore')
            if (field[u'id'] in fieldId_set and field_name == find_name):
                val = getattr(issue.fields, field['id'])
                if val != None:
                    return val
        return None       
    # download attachment from issue
    def file_download(self, issue_url):
        jira, issue = self.getJiraAndIssueFromURL(issue_url)
        for idx, attach in enumerate(issue.fields.attachment):
            print('%d. %s' % (idx+1, attach.filename))
        sys.stdout.write(' > ')
        idx=int(input())-1
        if idx < 0 and idx > len(issue.fields.attachment):
            print ('You must input correct value!.')
        else:
            attchment = issue.fields.attachment[idx]
            with open(attchment.filename, 'w') as writeF:
                writeF.write(attchment.get())
            print ('Success file write')
    # attach file to issue
    def file_attach(self, issue_url, file_path):
        jira, issue = self.getJiraAndIssueFromURL(issue_url)
        jira.add_attachment(issue, file_path)
    # return issue list (result of queries)
    def search_query(self, jira_type, query):
        jira=get_jira(profile=jira_type)
        issues = jira.search_issues(query)
        return jira, issues
    # return next status name after transition
    def next_status(self, jira, issue, transition):
        tr_dic = json.loads(json.dumps(jira.transitions(issue)))
        for tr in tr_dic:
            if (tr['name'] == transition):
		return tr['to']['name']
        return None
    # change status of issues to trasnsition, resolution
    def transition(self, jira, issues, transition, fields=None):
        if len(issues) < 1 or len(transition) < 1:
            return
        
        table_header = [['Branch', 'Key', 'Summary', 'From', 'To' ]]
        table_issues = []
        possible_idx = []
	transition_id = None

        for idx, issue in enumerate(issues):
            to_status = self.next_status(jira, issue, transition)
            if (to_status):
                if (transition_id == None): transition_id = jira.find_transitionid_by_name(issue, transition)
                to_status = "%s%s%s" % (Colors.OKGREEN, to_status, Colors.ENDC)
                possible_idx.append(idx)
            else:
                to_status = "%s%s%s" % (Colors.FAIL, issue.fields.status.name, Colors.ENDC)
            branch_name = self.customFieldValue(jira, issue, 'Branch')
            list_data = [branch_name if branch_name else '-', issue.key, issue.fields.summary, issue.fields.status.name, to_status]
            table_issues.append(list_data)
            idx = idx+1
        print(UnixTable(table_header+table_issues).table)

        if len(possible_idx) < 1:
            return
        
        answer = raw_input('Do you want to "%s" all? [y/n] ' % transition)
        if answer.lower() == 'y':
            for idx in possible_idx:
                try:
                    jira.transition_issue(issues[idx], transition_id, fields)
                except Exception as e:
                    print("%s%s%s" % (Colors.FAIL, e, Colors.ENDC))
        else:
            if len(possible_idx) < 2:
                return
            for idx in possible_idx:
                print(UnixTable(table_header + [table_issues[idx]]).table)
	        answer = raw_input('Do you want to "%s"? [y/n] ' % transition)
                if answer.lower() == 'y':
                    try:
                        jira.transition_issue(issues[idx], transition, fields)
                    except Exception as e:
                        print("%s%s%s" % (Colors.FAIL, e, Colors.ENDC))
    # update issue wrapper
    def update_issue(self, issue, field_id, contents):
        issue.update(fields={field_id:contents})

    # add comment wrapper
    def add_comment(self, jira, issue, comment):
        jira.add_comment(issue, comment)
