#!-*- coding:utf-8 -*-"

from trac.util.translation import _

def enc(str):
   return unicode(str).encode('utf-8')

def num_format(num):
    n = str(num)
    if n.endswith('.0'):
        return n[0:-2]
    return str(num)
   
def get_est_field(env):
    return env.config.get('worktime', 'estimatedhours_field', 'estimatedhours')   

def get_ticket_fileds(env):
    from trac.ticket.api import TicketSystem
    
    ticket_system = TicketSystem(env)
    ticket_fields = ticket_system.get_ticket_fields()
    ticket_field_map = {}
    for ticket_field in ticket_fields:
        ticket_field_map[ticket_field['name']] = ticket_field['label']
    
    return ticket_fields, ticket_field_map
        
        
def has_prefix_permission(env, req, prefix_perm):
    from trac.perm import PermissionSystem
    actions = PermissionSystem(env).get_user_permissions(req.authname)
    perms = [x for x in actions if x.startswith(prefix_perm)]
    return len(perms) > 0
    
def _get_accessable_groups(env, req, prefix_perm):
    from trac.perm import PermissionSystem
    actions = PermissionSystem(env).get_user_permissions(req.authname)
    groups = [x[len(prefix_perm):].lower() for x in actions if x.startswith(prefix_perm)]
    return groups

def get_accessable_users(group_providers, env, req, prefix_perm):
    groups = _get_accessable_groups(env, req, prefix_perm)
    if len(groups) == 0:
        from trac.perm import PermissionError
        raise PermissionError(prefix_perm + '...', None, env)
    
    all_users = get_all_users(env)
    
    target_workers = set([req.authname])
    
    for user in all_users:
        for group in _get_groups(group_providers, env, user):
            if group in groups:
                target_workers.add(user)
    return target_workers

def _get_groups(group_providers, env, user):
    from trac.perm import PermissionSystem
    # Get initial subjects
    groups = set([user])
    for provider in group_providers:
        for group in provider.get_permission_groups(user):
            groups.add(group)
    
    perms = PermissionSystem(env).get_all_permissions()
    repeat = True
    while repeat:
        repeat = False
        for subject, action in perms:
            if subject in groups and action.islower() and action not in groups:
                groups.add(action)
                repeat = True 
    
    return groups

def assert_report_view_permission(env, req):
    from trac.perm import PermissionSystem, PermissionError
    actions = PermissionSystem(env).get_user_permissions(req.authname)
    for action in actions:
        if action.startswith('WORKTIME_REPORT_VIEW'):
            return
    raise PermissionError('WORKTIME_REPORT_VIEW', None, env)
    

def assert_modify_permission(env, req):
    from trac.perm import PermissionSystem, PermissionError
    actions = PermissionSystem(env).get_user_permissions(req.authname)
    for action in actions:
        if action.startswith('WORKTIME_MODIFY'):
            return
    raise PermissionError('WORKTIME_MODIFY', None, env)
    
def get_all_users(env):
    """return the names of all known users in the trac environment"""
    return [i[0] for i in env.get_known_users()]

def urljoin(*args):
    return '/'.join(arg.strip('/') for arg in args)

def is_empty(string):
    return string in ('', None)

def is_closed(ticket):
    return not is_empty(ticket['resolution'])

def omit(string, num):
    if len(string) > num:
        return string[0:num] + '...'
    return string

def omit_line(string, num):
    if is_empty(string):
        return string
    
    lines = string.split('\n')
    if len(lines) > num:
        return '\n'.join(lines[0:num]) + '\n...'
    return string

def to_cc_list(cc_field):
    """Split a CC: value in a list of addresses."""
    if not cc_field:
        return []
    return [cc.strip() for cc in cc_field.split(',') if cc]

def append_or_get(list, obj):
    if obj in list:
        return list[list.index(obj)]
    else:
        list.append(obj)
        return obj

def to_ticket_group_nodes(tickets, group_fields):
    nodes = []
    node_id = 0

    for t in tickets:
        parent_node = None
        for gf in group_fields:
            node = Node(parent_node, gf, t, node_id)
            
            if node.is_ticket():
                nodes.append(node)
            else:
                node = append_or_get(nodes, node)
                
            if parent_node:
                parent_node.add_child(node)
            
            node_id += 1     
            parent_node = node

    return nodes

class Node(object):
    def __init__(self, parent, group, ticket, node_id):
        self.id = node_id
        self.group = group
        self.ticket = ticket
        self.name = ticket[group]
        self.parent = parent
        self.children = []
        
    def __eq__(self, other):
        if other is None:
            return False
        return self.name == other.name and \
            self.group == other.group and self.parent == other.parent
    
    def get_node_id(self):
        return 'node-%s' % str(self.id)
        
    def get_parent_node_id(self):
        if self.parent is None:
            return ''
        else:
            return 'child-of-%s' % self.parent.get_node_id()
    
    def add_child(self, child_node):
        if child_node not in self.children:
            self.children.append(child_node)
        
    def get_label(self, group_field):
        if self.group == group_field:
            if self.name == '':
                return '(None)'
            return self.name
        else:
            return ''
    
    def get_ticket_id(self):
        return self.ticket.id
    
    def is_ticket(self):
        return self.group == 'summary'
    
    def is_edge(self):
        return len(self.children) == 0
    