"""
    Action info
"""


import os
import urllib
from datetime import datetime
from urllib.parse import urlparse
import json
import lib
from lib.actions import Action
from .actionsearch import ActionSearch
from lib.alpm import AlpmBranch
from pycman import pkginfo


class ActionInfo(Action):

    @staticmethod
    def usage():
        return """
            info pkgname --unstable [--quiet or -q] [--files [--filter value]] : pacman -Si one branch
            info pkgname [--quiet or -q] : pacman -Si for all branches
            """

    def test(self):
        super().test()
        if not self.params.values:
            raise ValueError(f"No package to find !")
        return True

    def run(self):
        """ pacman -Qi in one or all branches """
        super().run()
        quiet = self.params.option('quiet', 'q')
        to_find = self.params.values.pop(0).lower()
        nb = [0]

        def get_info(branchname: str, pkgname: str, count: list):
            branch = AlpmBranch(branchname)
            pkg = branch.pkg_get(pkgname)
            if pkg:
                count[0] += 1
                txt = 'Branch'
                print(f"{txt:15}: {branch.color(branchname)}{branchname}{branch.color('none')}")
                if quiet:
                    print(f"{'Name':15}: {pkg.name}")
                    print(f"{'Version':15}: {pkg.version}")
                    print(f"{'Repository':15}: {pkg.db.name}")
                    print(f"{'Build Date ':15}: {datetime.fromtimestamp(pkg.builddate).strftime('%a %d %b %Y %X %Z')}")
                    print(f"{'Packager':15}: {pkg.packager}")
                else:
                    pkginfo.display_pkginfo(pkg, style='sync')
                return pkg
            return None

        if not self.params.branch:
            for br in AlpmBranch.BRANCHES:
                pkg = get_info(br, to_find, nb)
            AlpmBranch.aur_query(to_find)
        else:
            pkg = get_info(self.params.branch, to_find, nb)
            if self.params.branch != 'archlinux':
                self.show_archlinux(pkg)
            # display files
            if pkg and not quiet and self.params.option('files'):
                use_filter = self.params.option('filter')
                pkgfiles = AlpmBranch.read_files(self.params.branch, pkg)
                if use_filter and not isinstance(use_filter, bool):
                    pkgfiles = [p for p in pkgfiles if use_filter in p]
                if pkgfiles:
                    for pkgfile in pkgfiles:
                        print(pkgfile)
                    print("")

        if pkg and not quiet:
            if 'manjaro' in pkg.packager:
                url = f"https://gitlab.manjaro.org/packages/{pkg.db.name}/{pkg.name}"
                req = urllib.request.urlopen(url, timeout=5)
                # req.getcode() == always 200 !
                if req.geturl() == url:
                    print(f"{'Gitlab manjaro':15}: {url}")
            # version from last git tag
            if not self.params.branch:
                self.params.branch = 'unstable'
            self.show_gitlab(pkg, self.params.branch)
            self.show_github(pkg, self.params.branch)
            self.show_python(pkg, self.params.branch)
            self.show_snap(pkg, self.params.branch)
            self.show_flatpack(pkg, self.params.branch)

        if nb[0] < 1:
            # package not found ?
            if not self.params.branch:
                self.params.branch = 'unstable'
            self.params.options['--quiet'] = True
            ActionSearch(self.params).run(f"{to_find}.*")
            raise UserWarning(f"Nothing found !")


    def show_archlinux(self, pkg: object) ->bool:
        """ archlinux version """
        #can also use https://www.archlinux.org/packages/{pkg.db}/x86_64/{pkg.name}/json/
        if not pkg:
            return False
        branch = AlpmBranch('archlinux')
        pkga = branch.pkg_get(pkg.name)
        if pkga and pkg.version != pkga.version:
            print(f"{'Archlinux':15}: {branch.color(branch.branch)}{pkga.version}{branch.color('none')}")
            return True


    def show_python(self, pkg: object, branchname: str = 'unstable') ->bool:
        """ version from pypi.org """
        if not pkg.name.startswith('python-'):
            return
        if not branchname:
            branchname = 'unstable'
        try:
            with urllib.request.urlopen(f"https://pypi.org/pypi/{pkg.name[7:]}/json", timeout=7) as f_url:
                req = f_url.read()
                datas = json.loads(req)
                if datas:
                    print(f"\n{'Pypi.org':15}: {AlpmBranch.color(branchname)}{datas['info']['version']}{AlpmBranch.color('none')}")
                    return True
        except urllib.error.HTTPError:
            return False

    def show_gitlab(self, pkg: object, branchname: str = 'unstable') -> bool:
        """Display gitlab informations"""
        result = False
        if not 'gitlab' in pkg.url:
            return False
        if not branchname:
            branchname = 'unstable'
        id_gitlab = None
        namespace = urlparse(pkg.url).path.strip('/')
        if '/' in namespace:
            project = namespace.split('/')[-1]
        else:
            project = namespace

        value = lib.read_config_file(pkg.name, '-1').lower()
        if value != '-1':
            id_gitlab = value
        else:
            url = f"https://{urlparse(pkg.url).hostname}/api/v4/projects?scope=project&search={project}"
            try:
                with urllib.request.urlopen(url, timeout=8) as f_url:
                    req = f_url.read()
                    items = json.loads(req)
            except urllib.error.HTTPError:
                return False
            for item in items:
                if item['path_with_namespace'] == namespace:
                    id_gitlab = item['id']
                    #print('id_gitlab:', id_gitlab)
                    break

        if not id_gitlab:
            return False

        print(f"\n{AlpmBranch.color(branchname)}::{AlpmBranch.color('none')} from Gitlab")
        try:
            with urllib.request.urlopen(f"http://{urlparse(pkg.url).hostname}/api/v4/projects/{id_gitlab}/releases", timeout=7) as f_url:
                req = f_url.read()
                items = json.loads(req)
                for item in items:
                    print(f"{'last release':15}: {AlpmBranch.color(branchname)}{item['tag_name']}{AlpmBranch.color('none')} {item['name']}")
                    result = True
                    break
        except urllib.error.HTTPError:
            pass

        try:
            with urllib.request.urlopen(f"http://{urlparse(pkg.url).hostname}/api/v4/projects/{id_gitlab}/repository/tags", timeout=7) as f_url:
                req = f_url.read()
                items = json.loads(req)
                for item in items[:3]:
                    print(f"{'last tag':15}: {AlpmBranch.color(branchname)}{item['name']}{AlpmBranch.color('none')}")
                    result = True
        except urllib.error.HTTPError:
            pass

        try:
            with urllib.request.urlopen(f"http://{urlparse(pkg.url).hostname}/api/v4/projects/{id_gitlab}/repository/commits", timeout=7) as f_url:
                req = f_url.read()
                items = json.loads(req)
                for item in items[:1]:
                    print(f"{'last commit':15}: {AlpmBranch.color(branchname)}{item['committed_date'][:10]}{AlpmBranch.color('none')}")
                    result = True
        except urllib.error.HTTPError:
            pass

        return result

    def show_github(self, pkg: object, branchname: str = 'unstable') ->bool:
        # tag_name
        result = False
        if not 'github.com' in pkg.url:
            return result
        if not branchname:
            branchname = 'unstable'
        headers = {
            'Accept': 'application/vnd.github.quicksilver-preview+json',
            'User-Agent': 'manjaro Multi Branch Navigator',
            'Authorization': f"token {os.environ.get('GITHUB_TOKEN')}"
        }
        items = None
        namespace = urlparse(pkg.url).path.strip('/')

        # get releases
        try:
            req = urllib.request.Request(f"https://api.github.com/repos/{namespace}/releases/latest", headers=headers)
            with urllib.request.urlopen(req, timeout=7) as f_url:
                req = f_url.read()
                items = json.loads(req)
                if items and items['tag_name']:
                    print(f"\n{AlpmBranch.color(branchname)}::{AlpmBranch.color('none')} from Github")
                    print(f"{'last release':15}: {AlpmBranch.color(branchname)}{items['tag_name']}{AlpmBranch.color('none')} {items['name']}")
                    result = True
        except urllib.error.HTTPError:
            pass

        # get tags
        try:
            req = urllib.request.Request(f"https://api.github.com/repos/{namespace}/git/refs/tags", headers=headers)
            with urllib.request.urlopen(req, timeout=7) as f_url:
                req = f_url.read()
                tags = json.loads(req)
                if not result and tags:
                    print(f"\n{AlpmBranch.color(branchname)}::{AlpmBranch.color('none')} from Github")
                for atag in reversed(tags[-3:]):
                    tag = atag['ref'].split('/')[-1]
                    if items and tag == items['tag_name']:
                        break
                    print(f"{'last tag':15}: {AlpmBranch.color(branchname)}{tag}{AlpmBranch.color('none')}")
                    result = True
        except urllib.error.HTTPError:
            pass

        #last commit
        try:
            req = urllib.request.Request(f"https://api.github.com/repos/{namespace}/commits/master", headers=headers)
            with urllib.request.urlopen(req, timeout=7) as f_url:
                req = f_url.read()
                lcommit = json.loads(req)
                if not result and lcommit:
                    print(f"\n{AlpmBranch.color(branchname)}::{AlpmBranch.color('none')} from Github")
                ldate = lcommit['commit']['author']['date'][:10]
                print(f"{'last commit':15}: {AlpmBranch.color(branchname)}{ldate}{AlpmBranch.color('none')}")
                result = True
        except urllib.error.HTTPError:
            pass
        return result


    def show_snap(self, pkg: object, branchname: str = 'unstable') ->bool:
        url = f"https://search.apps.ubuntu.com/api/v1/search?q={pkg.name}"
        try:
            req = urllib.request.Request(url)
            with urllib.request.urlopen(req, timeout=7) as f_url:
                req = f_url.read()
                items = json.loads(req)['_embedded']
                for item in items['clickindex:package']:
                    print(f"\n{AlpmBranch.color(branchname)}::{AlpmBranch.color('none')} from Snap")
                    print(f"{'release':15}: {AlpmBranch.color(branchname)}{item['version']} {AlpmBranch.color('none')} {item['title']} {item['date_published'][:10]}")
                    #return True
        except urllib.error.HTTPError:
            return False

    def show_flatpack(self, pkg: object, branchname: str = 'unstable') ->bool:
        try:
            req = urllib.request.Request('https://flathub.org/api/v1/apps/')
            with urllib.request.urlopen(req, timeout=7) as f_url:
                req = f_url.read()
                for item in json.loads(req):
                    if f".{pkg.name}" in item['flatpakAppId'].lower():
                        print(f"\n{AlpmBranch.color(branchname)}::{AlpmBranch.color('none')} from FlatHub")
                        print(f"{'release':15}: {AlpmBranch.color(branchname)}{item['currentReleaseVersion']} {AlpmBranch.color('none')} {item['name']} {item['currentReleaseDate'][:10]}")
                        #return True
        except urllib.error.HTTPError:
            return False

    '''

    def show_appimage(self, pkg: object, branchname: str = 'unstable') ->bool:
        try:
            req = urllib.request.Request('https://appimage.github.io/feed.json')
            with urllib.request.urlopen(req, timeout=7) as f_url:
                req = f_url.read()
                for item in json.loads(req)['items']:
                    if f"{pkg.name}" in item['name'].lower():
                        print(f"\n{AlpmBranch.color(branchname)}::{AlpmBranch.color('none')} as Appimage")
                        # no version information !!!
                        #return True
        except urllib.error.HTTPError:
            return False
    '''
