"""
 format output
 use template and color code
    * colors: ($a,$u,$t,$s,$n) # and $c for curent ?
    * {%n %v:48} {%m:>12}
    * {$a%n$n %v:48} {%m:>12} # with color
"""

import time
from lib.alpm import AlpmBranch

class DisplayTemplate():
    """ general template """

    colors = {
        'a': AlpmBranch.COLORS['archlinux'],
        'u': AlpmBranch.COLORS['unstable'],
        't': AlpmBranch.COLORS['testing'],
        'g': AlpmBranch.COLORS['stable-staging'],
        's': AlpmBranch.COLORS['stable'],
        'n': AlpmBranch.COLORS['none'],
        'i': AlpmBranch.COLORS['i']
    }

    def __init__(self, template: str, color_default: str = 'n'):
        self.template = template
        self.templates = []
        self.results = []
        try:
            if color_default == "stable-staging":
                color_default = "g"
            self.colors['d'] = self.colors.get(color_default[:1], AlpmBranch.COLORS['none'])
        except IndexError:
            self.colors['d'] = AlpmBranch.COLORS['none']
        self.parse()

    def parse(self):
        templates = self.template.split('}')
        self.results = []

        for template in templates:
            if not template:
                continue
            align_left = True
            count = 0
            template = template.replace('{', '')
            pos = template.rfind(":")
            if pos > -1:
                count = template[pos+1:]
                if count.startswith('>'):
                    align_left = False
                    count = count[1:]
                try:
                    count = int(count)
                except ValueError:
                    count = 1
                    pos = 65000
            else:
                pos = 65000
            self.templates.append((template[0:pos], count, align_left)) # template, long

    def push(self, namespace: dict):
        self.results = []
        for template in self.templates:
            result = template[0]
            #push datas
            for key in namespace:
                result = result.replace(f"%{key}", str(namespace.get(key, '?')))
            # align columns
            # count '$' for exclude color codes
            while len(result) - result.count('$')*2 < template[1]:
                if template[2]: # align to left ?
                    result += ' '
                else:
                    result = ' '+result
            #push colors
            # TODO
            # if '$' is in description ?
            for key in self.colors:
                result = result.replace(f"${key}", str(self.colors.get(key, '')))
            self.results.append(result)
        return self.results

    def string(self, namespace=None):
        if namespace:
            self.push(namespace)
        result = ""
        for template in self.results:
            result = result + template
        return result.replace('\\n', "\n").replace('\\t', "\t")

    def debug(self):
        print('format:', self.template)
        for template in self.templates:
            print('template: ', template)
        for result in self.results:
            print('result: ', f"[{result}]")


class DisplayPkg(DisplayTemplate):
    """ template for one pkg """

    def __init__(self, template: str, branchname: str):
        super().__init__(template, branchname)
        self.branch = branchname

    @staticmethod
    def pkg_attr(key):
        """ convert if data is array """
        if key:
            if isinstance(key, list):
                return ' '.join(key)
            else:
                return key
        return ' '

    def push(self, pkg):
        """ push package datas in results """
        namespace = {
            'n': pkg.name,
            'v': pkg.version,
            'p': pkg.packager,
            'P': self.pkg_attr(pkg.provides),
            'D': self.pkg_attr(pkg.depends),
            'u': self.pkg_attr(pkg.url),
            'r': pkg.db.name,
            'd': pkg.desc,
            'G': self.pkg_attr(pkg.groups),
            'b': time.strftime('%Y-%m-%d', time.localtime(pkg.builddate)),
            'e': self.pkg_attr(pkg.base),
            'm': f"{int(pkg.size/1000):>6}", # size Ko
            'w': 'asdep' if pkg.reason == 1 else ''
        }
        return super().push(namespace)
