#    Author: Alex Savatieiev (osavatieiev@mirantis.com; a.savex@gmail.com)
#    Copyright 2019-2022 Mirantis, Inc.
import json
import os
import re
from copy import deepcopy

from cfg_checker.common import logger, logger_cli, nested_set
from cfg_checker.common.const import _mainteiners_index_filename
from cfg_checker.common.const import _mirantis_versions_filename
from cfg_checker.common.const import _other_versions_filename
from cfg_checker.common.const import _pkg_desc_archive
from cfg_checker.common.const import _repos_index_filename
from cfg_checker.common.const import _repos_info_archive
from cfg_checker.common.const import _repos_versions_archive
from cfg_checker.common.const import ubuntu_releases
from cfg_checker.common.const import kaas_ubuntu_active
from cfg_checker.common.const import mcp_active_tags as active_tags
from cfg_checker.common.file_utils import ensure_folder_exists
from cfg_checker.common.file_utils import get_gzipped_file
from cfg_checker.common.settings import pkg_dir
from cfg_checker.helpers.console_utils import Progress
from cfg_checker.helpers.tgz import TGZFile

import requests
from requests.exceptions import ConnectionError

ext = ".json"


def get_tag_label(_tag, parsed=False):
    # prettify the tag for printing
    if parsed:
        _label = "+ "
    else:
        _label = "  "

    if _tag.endswith(".update"):
        _label += "[updates] " + _tag.rsplit('.', 1)[0]
    elif _tag.endswith(".hotfix"):
        _label += " [hotfix] " + _tag.rsplit('.', 1)[0]
    else:
        _label += " "*10 + _tag

    return _label


def _get_value_index(_di, value, header=None):
    # Mainteiner names often uses specific chars
    # so make sure that value saved is str not str
    # Python2
    # _val = str(value, 'utf-8') if isinstance(value, str) else value
    # Python3 has always utf-8 decoded value
    _val = value
    if header:
        try:
            _index = next(i for i in _di if header in _di[i]['header'])
        except StopIteration:
            _index = str(len(_di) + 1)
            _di[_index] = {
                "header": header,
                "props": _val
            }
        finally:
            return _index
    else:
        try:
            _index = next(i for i in _di if _val in _di[i])
            # iterator not empty, find index
        except StopIteration:
            _index = str(len(_di) + 1)
            # on save, cast it as str
            _di[_index] = _val
        finally:
            return _index


def _safe_load(_f, _a):
    if _f in _a.list_files():
        logger_cli.debug(
            "... loading '{}':'{}'".format(
                _a.basefile,
                _f
            )
        )
        return json.loads(_a.get_file(_f, decode=True))
    else:
        return {}


def _n_url(url):
    if url[-1] == '/':
        return url
    else:
        return url + '/'


class ReposInfo(object):
    init_done = False

    def _init_vars(self):
        self.repos = []

    def _init_folders(self, arch_folder=None):
        if arch_folder:
            self._arch_folder = arch_folder
            self._repofile = os.path.join(arch_folder, _repos_info_archive)
        else:
            self._arch_folder = os.path.join(pkg_dir, "versions")
            self._repofile = os.path.join(
                self._arch_folder,
                _repos_info_archive
            )

    def __init__(self, arch_folder=None):
        # perform inits
        self._init_vars()
        self._init_folders(arch_folder)
        self.init_done = True

    def __call__(self, *args, **kwargs):
        if self.init_done:
            return self
        else:
            return self.__init__(self, *args, **kwargs)

    @staticmethod
    def _ls_repo_page(url):
        # Yes, this is ugly. But it works ok for small HTMLs.
        _a = "<a"
        _s = "href="
        _e = "\">"
        try:
            page = requests.get(url, timeout=60)
        except ConnectionError as e:
            logger_cli.error("# ERROR: {}".format(e.message))
            return [], []
        a = page.text.splitlines()
        # Comprehension for dirs. Anchors for ends with '-'
        _dirs = [ll[ll.index(_s)+6:ll.index(_e)-1]
                 for ll in a if ll.startswith(_a) and ll.endswith('-')]
        # Comprehension for files. Anchors ends with size
        _files = [ll[ll.index(_s)+6:ll.index(_e)]
                  for ll in a if ll.startswith(_a) and not ll.endswith('-')]

        return _dirs, _files

    def search_pkg(self, url, _list):
        # recoursive method to walk dists tree
        _dirs, _files = self._ls_repo_page(url)

        for _d in _dirs:
            # Search only in dists, ignore the rest
            if "dists" not in url and _d != "dists":
                continue
            _u = _n_url(url + _d)
            self.search_pkg(_u, _list)

        for _f in _files:
            if _f == "Packages.gz":
                _list.append(url + _f)
                logger.debug("... [F] '{}'".format(url + _f))

        return _list

    @staticmethod
    def _map_repo(_path_list, _r):
        for _pkg_path in _path_list:
            _l = _pkg_path.split('/')
            _kw = _l[_l.index('dists')+1:]
            _kw.reverse()
            _repo_item = {
                "arch": _kw[1][7:] if "binary" in _kw[1] else _kw[1],
                "type": _kw[2],
                "ubuntu-release": _kw[3],
                "filepath": _pkg_path
            }
            _r.append(_repo_item)

    def _find_tag(self, _t, _u, label=""):
        if label:
            _url = _n_url(_u + label)
            _label = _t + '.' + label
        else:
            _url = _u
            _label = _t
        _ts, _ = self._ls_repo_page(_url)
        if _t in _ts:
            logger.debug(
                "... found tag '{}' at '{}'".format(
                    _t,
                    _url
                )
            )
            return {
                _label: {
                    "baseurl": _n_url(_url + _t),
                    "all": {}
                }
            }
        else:
            return {}

    def fetch_repos(self, url, tag=None):
        base_url = _n_url(url)
        logger_cli.info("# Using '{}' as a repos source".format(base_url))

        logger_cli.info("# Gathering repos info (i.e. links to 'packages.gz')")
        # init repoinfo archive
        _repotgz = TGZFile(self._repofile)
        # prepare repo links
        _repos = {}
        if tag:
            # only one tag to process
            _repos.update(self._find_tag(tag, base_url))
            _repos.update(self._find_tag(tag, base_url, label="hotfix"))
            _repos.update(self._find_tag(tag, base_url, label="update"))
        else:
            # gather all of them
            _tags, _ = self._ls_repo_page(base_url)
            if "hotfix" in _tags:
                _tags.remove('hotfix')
            if "update" in _tags:
                _tags.remove('update')
            # Filter out not active tags
            logger_cli.info("Active tags for mcp: {}".format(
                ", ".join(active_tags)
            ))
            logger_cli.info("Active kaas ubuntu repos: {}".format(
                ", ".join(kaas_ubuntu_active)
            ))
            _active_tags = [t for t in _tags if t in active_tags]

            # search tags in subfolders
            _h_tags, _ = self._ls_repo_page(base_url + 'hotfix')
            _u_tags, _ = self._ls_repo_page(base_url + 'update')
            _active_tags.extend(
                [t for t in _h_tags if t not in _tags and t in active_tags]
            )
            _active_tags.extend(
                [t for t in _u_tags if t not in _tags and t in active_tags]
            )
            _progress = Progress(len(_active_tags))
            _index = 0
            for _tag in _active_tags:
                _repos.update(self._find_tag(_tag, base_url))
                _repos.update(self._find_tag(_tag, base_url, label="hotfix"))
                _repos.update(self._find_tag(_tag, base_url, label="update"))
                _index += 1
                _progress.write_progress(_index)
            _progress.end()

        # parse subtags
        for _label in _repos.keys():
            logger_cli.info("-> processing tag '{}'".format(_label))
            _name = _label + ".json"
            if _repotgz.has_file(_name) and not tag:
                logger_cli.info(
                    "-> skipping, '{}' already has '{}'".format(
                        _repos_info_archive,
                        _name
                    )
                )
                continue
            # process the tag
            _repo = _repos[_label]
            _baseurl = _repos[_label]["baseurl"]
            # get the subtags
            _sub_tags, _ = self._ls_repo_page(_baseurl)
            _total_index = len(_sub_tags)
            _index = 0
            _progress = Progress(_total_index)
            logger_cli.debug(
                "... found {} subtags for '{}'".format(
                    len(_sub_tags),
                    _label
                )
            )
            # save the url and start search
            for _stag in _sub_tags:
                _u = _baseurl + _stag
                _index += 1
                logger_cli.debug(
                    "... searching repos in '{}/{}'".format(
                        _label,
                        _stag
                    )
                )

                # Searching Package collections
                if _stag in ubuntu_releases or _stag in kaas_ubuntu_active:
                    # if stag is the release, this is all packages
                    _repo["all"][_stag] = []
                    _repo["all"]["url"] = _n_url(_u)
                    _path_list = self.search_pkg(_n_url(_u), [])
                    self._map_repo(_path_list, _repo["all"][_stag])
                    logger_cli.info(
                        "-> found {} dists".format(
                            len(_repo["all"][_stag])
                        )
                    )

                else:
                    # each subtag might have any ubuntu release
                    # so iterate them
                    _repo[_stag] = {
                        "url": _n_url(_u)
                    }
                    _releases, _ = self._ls_repo_page(_n_url(_u))
                    for _rel in _releases:
                        if _rel not in ubuntu_releases:
                            logger_cli.debug(
                                "... skipped unknown ubuntu release: "
                                "'{}' in '{}'".format(
                                    _rel,
                                    _u
                                )
                            )
                        else:
                            _rel_u = _n_url(_u) + _rel
                            _repo[_stag][_rel] = []
                            _path_list = self.search_pkg(_n_url(_rel_u), [])
                            self._map_repo(
                                _path_list,
                                _repo[_stag][_rel]
                            )
                            logger_cli.info(
                                "-> found {} dists for '{}'".format(
                                    len(_repo[_stag][_rel]),
                                    _rel
                                )
                            )
                _progress.write_progress(_index)

            _progress.end()
            _name = _label + ext
            _repotgz.add_file(
                _name,
                buf=json.dumps(_repo, indent=2),
                replace=True
            )
            logger_cli.info(
                "-> archive '{}' updated with '{}'".format(
                    self._repofile,
                    _name
                )
            )

        return

    def list_tags(self, splitted=False):
        _files = TGZFile(self._repofile).list_files()
        # all files in archive with no '.json' part
        _all = set([f.rsplit('.', 1)[0] for f in _files])
        if splitted:
            # files that ends with '.update'
            _updates = set([f for f in _all if f.find('update') >= 0])
            # files that ends with '.hotfix'
            _hotfix = set([f for f in _all if f.find('hotfix') >= 0])
            # remove updates and hotfix tags from all. The true magic of SETs
            _all = _all - _updates - _hotfix
            # cut updates and hotfix endings
            _updates = [f.rsplit('.', 1)[0] for f in _updates]
            _hotfix = [f.rsplit('.', 1)[0] for f in _hotfix]

            return _all, _updates, _hotfix
        else:
            # dynamic import
            import re
            _all = list(_all)
            # lexical tags
            _lex = [s for s in _all if not s[0].isdigit()]
            _lex.sort()
            # tags with digits
            _dig = [s for s in _all if s[0].isdigit()]
            _dig = sorted(
                _dig,
                key=lambda x: tuple(int(i) for i in re.findall(r"\d+", x)[:3])
            )

            return _dig + _lex

    def get_repoinfo(self, tag):
        _tgz = TGZFile(self._repofile)
        _buf = _tgz.get_file(tag + ext, decode=True)
        return json.loads(_buf)


class RepoManager(object):
    init_done = False

    def _init_folders(self, arch_folder=None):
        logger_cli.info("# Loading package versions data")
        # overide arch folder if needed
        if arch_folder:
            self._arch_folder = arch_folder
        else:
            self._arch_folder = os.path.join(pkg_dir, "versions")

        self._versions_arch = os.path.join(
            self._arch_folder,
            _repos_versions_archive
        )
        self._desc_arch = os.path.join(self._arch_folder, _pkg_desc_archive)

    def _init_vars(self, info_class):
        # RepoInfo instance init
        if info_class:
            self._info_class = info_class
        else:
            self._info_class = ReposInfo()
        # archives
        self._apps_filename = "apps.json"

        # repository index
        self._repo_index = {}
        self._mainteiners_index = {}

        self._apps = {}

        # init package versions storage
        self._versions_mirantis = {}
        self._versions_other = {}

    def _init_archives(self):
        # Init version files
        self.versionstgz = TGZFile(
            self._versions_arch,
            label="MCP Configuration Checker: Package versions archive"
        )
        self.desctgz = TGZFile(
            self._desc_arch,
            label="MCP Configuration Checker: Package descriptions archive"
        )

        # section / app
        self._apps = _safe_load(
            self._apps_filename,
            self.desctgz
        )

        # indices
        self._repo_index = _safe_load(
            _repos_index_filename,
            self.versionstgz
        )
        self._mainteiners_index = _safe_load(
            _mainteiners_index_filename,
            self.versionstgz
        )

        # versions
        self._versions_mirantis = _safe_load(
            _mirantis_versions_filename,
            self.versionstgz
        )
        self._versions_other = _safe_load(
            _other_versions_filename,
            self.versionstgz
        )

    def __init__(self, arch_folder=None, info_class=None):
        # Perform inits
        self._init_vars(info_class)
        self._init_folders(arch_folder)
        # Ensure that versions folder exists
        logger_cli.debug(ensure_folder_exists(self._arch_folder))
        # Preload/create archives
        self._init_archives()
        self.init_done = True

    def __call__(self, *args, **kwargs):
        if self.init_done:
            return self
        else:
            return self.__init__(self, *args, **kwargs)

    def _create_repo_header(self, p):
        _header = "_".join([
            p['tag'],
            p['subset'],
            p['release'],
            p['ubuntu-release'],
            p['type'],
            p['arch']
        ])
        return _get_value_index(self._repo_index, p, header=_header)

    def _get_indexed_values(self, pair):
        _h, _m = pair.split('-')
        return self._repo_index[_h], self._mainteiners_index[_m]

    def _update_pkg_version(self, _d, n, v, md5, s, a, h_index, m_index):
        """Method updates package version record in global dict
        """
        # 'if'*4 operation is pretty expensive when using it 100k in a row
        # so try/except is a better way to go, even faster than 'reduce'
        _pair = "-".join([h_index, m_index])
        _info = {
            'repo': [_pair],
            'section': s,
            'app': a
        }
        try:
            # try to load list
            _list = _d[n][v][md5]['repo']
            # cast it as set() and union()
            _list = set(_list).union([_pair])
            # cast back as set() is not serializeable
            _d[n][v][md5]['repo'] = list(_list)
            return False
        except KeyError:
            # ok, this is fresh pkg. Do it slow way.
            if n in _d:
                # there is such pkg already
                if v in _d[n]:
                    # there is such version, check md5
                    if md5 in _d[n][v]:
                        # just add new repo header
                        if _pair not in _d[n][v][md5]['repo']:
                            _d[n][v][md5]['repo'].append(_pair)
                    else:
                        # check if such index is here...
                        _existing = filter(
                            lambda i: _pair in _d[n][v][i]['repo'],
                            _d[n][v]
                        )
                        if _existing:
                            # Yuck! Same version had different MD5
                            _r, _m = self._get_indexed_values(_pair)
                            logger_cli.error(
                                "# ERROR: Package version has multiple MD5s "
                                "in '{}': {}:{}:{}".format(
                                    _r,
                                    n,
                                    v,
                                    md5
                                )
                            )
                        _d[n][v][md5] = _info
                else:
                    # this is new version for existing package
                    _d[n][v] = {
                        md5: _info
                    }
                return False
            else:
                # this is new pakcage
                _d[n] = {
                    v: {
                        md5: _info
                    }
                }
                return True

    def _save_repo_descriptions(self, repo_props, desc):
        # form the filename for the repo and save it
        self.desctgz.add_file(
            self._create_repo_header(repo_props),
            json.dumps(desc)
        )

    # def get_description(self, repo_props, name, md5=None):
    #     """Gets target description
    #     """
    #     _filename = self._create_repo_header(repo_props)
    #     # check if it is present in cache
    #     if _filename in self._desc_cache:
    #         _descs = self._desc_cache[_filename]
    #     else:
    #         # load data
    #         _descs = self.desctgz.get_file(_filename)
    #         # Serialize it
    #         _descs = json.loads(_descs)
    #         self._desc_cache[_filename] = _descs
    #     # return target desc
    #     if name in _descs and md5 in _descs[name]:
    #         return _descs[name][md5]
    #     else:
    #         return None

    def parse_tag(self, tag, descriptions=False, apps=False):
        """Download and parse Package.gz files for specific tag
        By default, descriptions not saved
        due to huge resulting file size and slow processing
        """
        # init gzip and downloader
        _info = self._info_class.get_repoinfo(tag)
        # calculate Packages.gz files to process
        _baseurl = _info.pop("baseurl")
        _total_components = len(_info.keys()) - 1
        _ubuntu_package_repos = 0
        _other_repos = 0
        for _c, _d in _info.items():
            for _ur, _l in _d.items():
                if _ur in ubuntu_releases or _ur in kaas_ubuntu_active:
                    _ubuntu_package_repos += len(_l)
                elif _ur != 'url':
                    _other_repos += len(_l)
        logger_cli.info(
            "-> loaded repository info for '{}'.\n"
            "  '{}', {} components, {} ubuntu repos, {} other/uknown".format(
                _baseurl,
                tag,
                _total_components,
                _ubuntu_package_repos,
                _other_repos
            )
        )
        # init progress bar
        _progress = Progress(_ubuntu_package_repos)
        _index = 0
        _processed = 0
        _new = 0
        for _c, _d in _info.items():
            # we do not need url here, just get rid of it
            if 'url' in _d:
                _d.pop('url')
            # _url =  if 'url' in _d else _baseurl + _c
            for _ur, _l in _d.items():
                # iterate package collections
                for _p in _l:
                    # descriptions
                    if descriptions:
                        _descriptions = {}
                    # download and unzip
                    _index += 1
                    _progress.write_progress(
                        _index,
                        note="/ {} {} {} {} {}, GET 'Packages.gz'".format(
                            _c,
                            _ur,
                            _p['ubuntu-release'],
                            _p['type'],
                            _p['arch']
                        )
                    )
                    _raw = get_gzipped_file(_p['filepath'])
                    if not _raw:
                        # empty repo...
                        _progress.clearline()
                        logger_cli.warning(
                            "# WARNING: Empty file: '{}'".format(
                                _p['filepath']
                            )
                        )
                        continue
                    else:
                        _raw = _raw.decode("utf-8")
                    _progress.write_progress(
                        _index,
                        note="/ {} {} {} {} {}, {}/{}".format(
                            _c,
                            _ur,
                            _p['ubuntu-release'],
                            _p['type'],
                            _p['arch'],
                            _processed,
                            _new
                        )
                    )
                    _lines = _raw.splitlines()
                    # break lines collection into isolated pkg data
                    _pkg = {
                        "tag": tag,
                        "subset": _c,
                        "release": _ur
                    }
                    _pkg.update(_p)
                    _desc = {}
                    _key = _value = ""
                    # if there is no empty line at end, add it
                    if _lines[-1] != '':
                        _lines.append('')
                    # Process lines
                    for _line in _lines:
                        if not _line:
                            # if the line is empty, process pkg data gathered
                            _name = _desc['package']
                            _md5 = _desc['md5sum']
                            _version = _desc['version']
                            _mainteiner = _desc['maintainer']

                            if 'source' in _desc:
                                _ap = _desc['source'].lower()
                            else:
                                _ap = "-"

                            if apps:
                                # insert app
                                _sc = _desc['section'].lower()
                                if 'source' in _desc:
                                    _ap = _desc['source'].lower()
                                else:
                                    _ap = "-"

                                try:
                                    _tmp = set(self._apps[_sc][_ap][_name])
                                    _tmp.add(_desc['architecture'])
                                    self._apps[_sc][_ap][_name] = list(_tmp)
                                except KeyError:
                                    nested_set(
                                        self._apps,
                                        [_sc, _ap, _name],
                                        [_desc['architecture']]
                                    )

                            # Check is mainteiner is Mirantis
                            if _mainteiner.endswith("@mirantis.com>"):
                                # update mirantis versions
                                if self._update_pkg_version(
                                    self._versions_mirantis,
                                    _name,
                                    _version,
                                    _md5,
                                    _desc['section'].lower(),
                                    _ap,
                                    self._create_repo_header(_pkg),
                                    _get_value_index(
                                        self._mainteiners_index,
                                        _mainteiner
                                    )
                                ):
                                    _new += 1
                            else:
                                # update other versions
                                if self._update_pkg_version(
                                    self._versions_other,
                                    _name,
                                    _version,
                                    _md5,
                                    _desc['section'].lower(),
                                    _ap,
                                    self._create_repo_header(_pkg),
                                    _get_value_index(
                                        self._mainteiners_index,
                                        _mainteiner
                                    )
                                ):
                                    _new += 1

                            if descriptions:
                                _d_new = {
                                    _md5: deepcopy(_desc)
                                }
                                try:
                                    _descriptions[_name].update(_d_new)
                                except KeyError:
                                    _descriptions[_name] = _d_new
                            # clear the data for next pkg
                            _processed += 1
                            _desc = {}
                            _key = ""
                            _value = ""
                        elif _line.startswith(' '):
                            _desc[_key] += "\n{}".format(_line)
                        else:
                            if _line.endswith(":"):
                                _key = _line[:-1]
                                _value = ""
                            else:
                                _key, _value = _line.split(": ", 1)
                            _key = _key.lower()
                            _desc[_key] = _value
                    # save descriptions if needed
                    if descriptions:
                        _progress.clearline()
                        self._save_repo_descriptions(_pkg, _descriptions)

        _progress.end()
        # backup headers to disk
        self.versionstgz.add_file(
            _repos_index_filename,
            json.dumps(self._repo_index),
            replace=True
        )
        self.versionstgz.add_file(
            _mainteiners_index_filename,
            json.dumps(self._mainteiners_index),
            replace=True
        )
        if apps:
            self.desctgz.add_file(
                self._apps_filename,
                json.dumps(self._apps),
                replace=True
            )

        return

    def fetch_versions(self, tag, descriptions=False, apps=False):
        """Executes parsing for specific tag
        """
        if descriptions:
            logger_cli.warning(
                "\n\n# !!! WARNING: Saving repo descriptions "
                "consumes huge amount of disk space\n\n"
            )
        # if there is no such tag, parse it from repoinfo
        logger_cli.info("# Fetching versions for {}".format(tag))
        self.parse_tag(tag, descriptions=descriptions, apps=apps)
        logger_cli.info("-> saving updated versions")
        self.versionstgz.add_file(
            _mirantis_versions_filename,
            json.dumps(self._versions_mirantis),
            replace=True
        )
        self.versionstgz.add_file(
            _other_versions_filename,
            json.dumps(self._versions_other),
            replace=True
        )

    def build_repos(self, url, tag=None):
        """Builds versions data for selected tag, or for all of them
        """
        # recoursively walk the mirrors
        # and gather all of the repos for 'tag' or all of the tags
        self._info_class.fetch_repos(url, tag=tag)

    def _build_action(self, url, tags):
        for t in tags:
            logger_cli.info("# Building repo info for '{}'".format(t))
            self.build_repos(url, tag=t)

    def get_available_tags(self, tag=None):
        # Populate action tags
        major, updates, hotfix = self._info_class.list_tags(splitted=True)

        _tags = []
        if tag in major:
            _tags.append(tag)
        if tag in updates:
            _tags.append(tag + ".update")
        if tag in hotfix:
            _tags.append(tag + ".hotfix")

        return _tags

    def action_for_tag(
        self,
        url,
        tag,
        action=None,
        descriptions=None,
        apps=None
    ):
        """Executes action for every tag from all collections
        """
        if not action:
            logger_cli.info("# No action set, nothing to do")
        # See if this is a list action
        if action == "list":
            _all = self._info_class.list_tags()
            if _all:
                # Print pretty list and exit
                logger_cli.info("# Tags available at '{}':".format(url))
                for t in _all:
                    _ri = self._repo_index
                    _isparsed = any(
                        [k for k, v in _ri.items()
                         if v['props']['tag'] == t]
                    )
                    if _isparsed:
                        logger_cli.info(get_tag_label(t, parsed=True))
                    else:
                        logger_cli.info(get_tag_label(t))
            else:
                logger_cli.info("# Not tags parsed yet for '{}':".format(url))

            # exit
            return

        if action == "build":
            self._build_action(url, [tag])

        # Populate action tags
        _action_tags = self.get_available_tags(tag)

        if not _action_tags:
            logger_cli.info(
                "# Tag of '{}' not found. "
                "Consider rebuilding repos info.".format(tag)
            )
        else:
            logger_cli.info(
                "-> tags to process: {}".format(
                    ", ".join(_action_tags)
                )
            )
        # Execute actions
        if action == "fetch":
            for t in _action_tags:
                self.fetch_versions(t, descriptions=descriptions, apps=apps)

        logger_cli.info("# Done.")

    def show_package(self, name):
        # get the package data
        _p = self.get_package_versions(name)
        if not _p:
            logger_cli.warning(
                "# WARNING: Package '{}' not found".format(name)
            )
        else:
            # print package info using sorted tags from headers
            # Package: name
            # [u/h] tag \t <version>
            #           \t <version>
            # <10symbols> \t <md5> \t sorted headers with no tag
            # ...
            # section
            for _s in sorted(_p):
                # app
                for _a in sorted(_p[_s]):
                    _o = ""
                    _mm = []
                    # get and sort tags
                    for _v in sorted(_p[_s][_a]):
                        _o += "\n" + " "*8 + _v + ':\n'
                        # get and sort tags
                        for _md5 in sorted(_p[_s][_a][_v]):
                            _o += " "*16 + _md5 + "\n"
                            # get and sort repo headers
                            for _r in sorted(_p[_s][_a][_v][_md5]):
                                _o += " "*24 + _r.replace('_', ' ') + '\n'
                                _m = _p[_s][_a][_v][_md5][_r]["maintainer"]
                                if _m not in _mm:
                                    _mm.append(_m)

                    logger_cli.info(
                        "\n# Package: {}/{}/{}\nMaintainers: {}".format(
                            _s,
                            _a,
                            name,
                            ", ".join(_mm)
                        )
                    )

                    logger_cli.info(_o)

    @staticmethod
    def get_apps(versions, name):
        _all = True if name == '*' else False
        _s_max = _a_max = _p_max = _v_max = 0
        _rows = []
        for _p in versions.keys():
            _vs = versions[_p]
            for _v, _d1 in _vs.items():
                for _md5, _info in _d1.items():
                    if _all or name == _info['app']:
                        _s_max = max(len(_info['section']), _s_max)
                        _a_max = max(len(_info['app']), _a_max)
                        _p_max = max(len(_p), _p_max)
                        _v_max = max(len(_v), _v_max)
                        _rows.append([
                            _info['section'],
                            _info['app'],
                            _p,
                            _v,
                            _md5,
                            len(_info['repo'])
                        ])
        # format columns
        # section
        _fmt = "{:"+str(_s_max)+"} "
        # app
        _fmt += "{:"+str(_a_max)+"} "
        # package name
        _fmt += "{:"+str(_p_max)+"} "
        # version
        _fmt += "{:"+str(_v_max)+"} "
        # md5 and number of repos is fixed
        _fmt += "{} in {} repos"

        # fill rows
        _rows = [_fmt.format(s, a, p, v, m, l) for s, a, p, v, m, l in _rows]
        _rows.sort()
        return _rows

    def show_app(self, name):
        c = 0
        rows = self.get_apps(self._versions_mirantis, name)
        if rows:
            logger_cli.info("\n# Mirantis packages for '{}'".format(name))
            logger_cli.info("\n".join(rows))
            c += 1
        rows = self.get_apps(self._versions_other, name)
        if rows:
            logger_cli.info("\n# Other packages for '{}'".format(name))
            logger_cli.info("\n".join(rows))
            c += 1
        if c == 0:
            logger_cli.info("\n# No app found for '{}'".format(name))

    def get_mirantis_pkg_names(self):
        # Mirantis maintainers only
        return set(
            self._versions_mirantis.keys()
        ) - set(
            self._versions_other.keys()
        )

    def get_other_pkg_names(self):
        # Non-mirantis Maintainers
        return set(
            self._versions_other.keys()
        ) - set(
            self._versions_mirantis.keys()
        )

    def get_mixed_pkg_names(self):
        # Mixed maintainers
        return set(
            self._versions_mirantis.keys()
        ).intersection(set(
            self._versions_other.keys()
        ))

    def is_mirantis(self, name, tag=None):
        """Method checks if this package is mainteined
        by mirantis in target tag repo
        """
        if name in self._versions_mirantis:
            # check tag
            if tag:
                _pkg = self.get_package_versions(
                    name,
                    tagged=True
                )
                _tags = []
                for s in _pkg.keys():
                    for a in _pkg[s].keys():
                        for t in _pkg[s][a].keys():
                            _tags.append(t)
                if any([t.startswith(tag) for t in _tags]):
                    return True
                else:
                    return None
            else:
                return True
        elif name in self._versions_other:
            # check tag
            if tag:
                _pkg = self.get_package_versions(
                    name,
                    tagged=True
                )
                _tags = []
                for s in _pkg.keys():
                    for a in _pkg[s].keys():
                        for t in _pkg[s][a].keys():
                            _tags.append(t)
                if any([t.startswith(tag) for t in _tags]):
                    return False
                else:
                    return None
            else:
                return False
        else:
            logger.error(
                "# ERROR: package '{}' not found "
                "while determining maintainer".format(
                    name
                )
            )
            return None

    def get_filtered_versions(
        self,
        name,
        tag=None,
        include=None,
        exclude=None
    ):
        """Method gets all the versions for the package
        and filters them using keys above
        """
        if tag:
            tag = str(tag) if not isinstance(tag, str) else tag
        _out = {}
        _vs = self.get_package_versions(name, tagged=True)
        # iterate to filter out keywords
        for s, apps in _vs.items():
            for a, _tt in apps.items():
                for t, vs in _tt.items():
                    # filter tags
                    if tag and t != tag and t.rsplit('.', 1)[0] != tag:
                        continue
                    # Skip hotfix tag
                    if t == tag + ".hotfix":
                        continue
                    for v, rp in vs.items():
                        for h, p in rp.items():
                            # filter headers with all keywords matching
                            _h = re.split(r"[\-\_]+", h)
                            _included = all([kw in _h for kw in include])
                            _excluded = any([kw in _h for kw in exclude])
                            if not _included or _excluded:
                                continue
                            else:
                                nested_set(_out, [s, a, v], [])
                                _dat = {
                                    "header": h
                                }
                                _dat.update(p)
                                _out[s][a][v].append(_dat)
        return _out

    def get_package_versions(self, name, tagged=False):
        """Method builds package version structure
        with repository properties included
        """
        # get data
        _vs = {}

        if name in self._versions_mirantis:
            _vs.update(self._versions_mirantis[name])
        if name in self._versions_other:
            _vs.update(self._versions_other[name])

        # insert repo data, insert props into headers place
        _package = {}
        if tagged:
            for _v, _d1 in _vs.items():
                # use tag as a next step
                for _md5, _info in _d1.items():
                    _s = _info['section']
                    _a = _info['app']
                    for _pair in _info['repo']:
                        _rp = {}
                        # extract props for a repo
                        _r, _m = self._get_indexed_values(_pair)
                        # get tag
                        _tag = _r["props"]["tag"]
                        # cut tag from the header
                        _cut_head = _r["header"].split("_", 1)[1]
                        # populate dict
                        _rp["maintainer"] = _m
                        _rp["md5"] = _md5
                        _rp.update(_r["props"])
                        nested_set(
                            _package,
                            [_s, _a, _tag, _v, _cut_head],
                            _rp
                        )
        else:
            for _v, _d1 in _vs.items():
                for _md5, _info in _d1.items():
                    _s = _info['section']
                    _a = _info['app']
                    for _pair in _info['repo']:
                        _r, _m = self._get_indexed_values(_pair)
                        _info["maintainer"] = _m
                        _info.update(_r["props"])
                        nested_set(
                            _package,
                            [_s, _a, _v, _md5, _r["header"]],
                            _info
                        )

        return _package

    def parse_repos(self):
        # all tags to check
        major, updates, hotfix = self._info_class.list_tags(splitted=True)

        # major tags
        logger_cli.info("# Processing major tags")
        for _tag in major:
            self.fetch_versions(_tag)

        # updates tags
        logger_cli.info("# Processing update tags")
        for _tag in updates:
            self.fetch_versions(_tag + ".update")

        # hotfix tags
        logger_cli.info("# Processing hotfix tags")
        for _tag in hotfix:
            self.fetch_versions(_tag + ".hotfix")
