#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#

def create_socket(url, d):
    import urllib
    from bb.utils import export_proxies

    export_proxies(d)
    return urllib.request.urlopen(url)

def get_links_from_url(url, d):
    "Return all the href links found on the web location"

    from bs4 import BeautifulSoup, SoupStrainer

    soup = BeautifulSoup(create_socket(url,d), "html.parser", parse_only=SoupStrainer("a"))
    hyperlinks = []
    for line in soup.find_all('a', href=True):
        hyperlinks.append(line['href'].strip('/'))
    return hyperlinks

def find_latest_numeric_release(url, d):
    "Find the latest listed numeric release on the given url"
    max=0
    maxstr=""
    for link in get_links_from_url(url, d):
        try:
            # TODO use bb.utils.vercmp_string_op()
            release = float(link)
        except:
            release = 0
        if release > max:
            max = release
            maxstr = link
    return maxstr

def is_src_rpm(name):
    "Check if the link is pointing to a src.rpm file"
    return name.endswith(".src.rpm")

def package_name_from_srpm(srpm):
    "Strip out the package name from the src.rpm filename"

    # ca-certificates-2016.2.7-1.0.fc24.src.rpm
    # ^name           ^ver     ^release^removed
    (name, version, release) = srpm.replace(".src.rpm", "").rsplit("-", 2)
    return name

def get_source_package_list_from_url(url, section, d):
    "Return a sectioned list of package names from a URL list"

    bb.note("Reading %s: %s" % (url, section))
    links = get_links_from_url(url, d)
    srpms = filter(is_src_rpm, links)
    names_list = map(package_name_from_srpm, srpms)

    new_pkgs = set()
    for pkgs in names_list:
       new_pkgs.add(pkgs + ":" + section)
    return new_pkgs

def get_source_package_list_from_url_by_letter(url, section, d):
    import string
    from urllib.error import HTTPError
    packages = set()
    for letter in (string.ascii_lowercase + string.digits):
        # Not all subfolders may exist, so silently handle 404
        try:
            packages |= get_source_package_list_from_url(url + "/" + letter, section, d)
        except HTTPError as e:
            if e.code != 404: raise
    return packages

def get_latest_released_fedora_source_package_list(d):
    "Returns list of all the name os packages in the latest fedora distro"
    latest = find_latest_numeric_release("http://archive.fedoraproject.org/pub/fedora/linux/releases/", d)
    package_names = get_source_package_list_from_url_by_letter("http://archive.fedoraproject.org/pub/fedora/linux/releases/%s/Everything/source/tree/Packages/" % latest, "main", d)
    package_names |= get_source_package_list_from_url_by_letter("http://archive.fedoraproject.org/pub/fedora/linux/updates/%s/SRPMS/" % latest, "updates", d)
    return latest, package_names

def get_latest_released_opensuse_source_package_list(d):
    "Returns list of all the name os packages in the latest opensuse distro"
    latest = find_latest_numeric_release("http://download.opensuse.org/source/distribution/leap", d)

    package_names = get_source_package_list_from_url("http://download.opensuse.org/source/distribution/leap/%s/repo/oss/suse/src/" % latest, "main", d)
    package_names |= get_source_package_list_from_url("http://download.opensuse.org/update/leap/%s/oss/src/" % latest, "updates", d)
    return latest, package_names

def get_latest_released_clear_source_package_list(d):
    latest = find_latest_numeric_release("https://download.clearlinux.org/releases/", d)
    package_names = get_source_package_list_from_url("https://download.clearlinux.org/releases/%s/clear/source/SRPMS/" % latest, "main", d)
    return latest, package_names

def find_latest_debian_release(url, d):
    "Find the latest listed debian release on the given url"

    releases = [link.replace("Debian", "")
                for link in get_links_from_url(url, d)
                if link.startswith("Debian")]
    releases.sort()
    try:
        return releases[-1]
    except:
        return "_NotFound_"

def get_debian_style_source_package_list(url, section, d):
    "Return the list of package-names stored in the debian style Sources.gz file"
    import gzip

    package_names = set()
    for line in gzip.open(create_socket(url, d), mode="rt"):
        if line.startswith("Package:"):
            pkg = line.split(":", 1)[1].strip()
            package_names.add(pkg + ":" + section)
    return package_names

def get_latest_released_debian_source_package_list(d):
    "Returns list of all the name of packages in the latest debian distro"
    latest = find_latest_debian_release("http://ftp.debian.org/debian/dists/", d)
    url = "http://ftp.debian.org/debian/dists/stable/main/source/Sources.gz"
    package_names = get_debian_style_source_package_list(url, "main", d)
    url = "http://ftp.debian.org/debian/dists/stable-proposed-updates/main/source/Sources.gz"
    package_names |= get_debian_style_source_package_list(url, "updates", d)
    return latest, package_names

def find_latest_ubuntu_release(url, d):
    """
    Find the latest listed Ubuntu release on the given ubuntu/dists/ URL.

    To avoid matching development releases look for distributions that have
    updates, so the resulting distro could be any supported release.
    """
    url += "?C=M;O=D" # Descending Sort by Last Modified
    for link in get_links_from_url(url, d):
        if "-updates" in link:
            distro = link.replace("-updates", "")
            return distro
    return "_NotFound_"

def get_latest_released_ubuntu_source_package_list(d):
    "Returns list of all the name os packages in the latest ubuntu distro"
    latest = find_latest_ubuntu_release("http://archive.ubuntu.com/ubuntu/dists/", d)
    url = "http://archive.ubuntu.com/ubuntu/dists/%s/main/source/Sources.gz" % latest
    package_names = get_debian_style_source_package_list(url, "main", d)
    url = "http://archive.ubuntu.com/ubuntu/dists/%s-updates/main/source/Sources.gz" % latest
    package_names |= get_debian_style_source_package_list(url, "updates", d)
    return latest, package_names

def create_distro_packages_list(distro_check_dir, d):
    import shutil

    pkglst_dir = os.path.join(distro_check_dir, "package_lists")
    bb.utils.remove(pkglst_dir, True)
    bb.utils.mkdirhier(pkglst_dir)

    per_distro_functions = (
                            ("Debian", get_latest_released_debian_source_package_list),
                            ("Ubuntu", get_latest_released_ubuntu_source_package_list),
                            ("Fedora", get_latest_released_fedora_source_package_list),
                            ("openSUSE", get_latest_released_opensuse_source_package_list),
                            ("Clear", get_latest_released_clear_source_package_list),
                           )

    for name, fetcher_func in per_distro_functions:
        try:
            release, package_list = fetcher_func(d)
        except Exception as e:
            bb.warn("Cannot fetch packages for %s: %s" % (name, e))
        bb.note("Distro: %s, Latest Release: %s, # src packages: %d" % (name, release, len(package_list)))
        if len(package_list) == 0:
            bb.error("Didn't fetch any packages for %s %s" % (name, release))

        package_list_file = os.path.join(pkglst_dir, name + "-" + release)
        with open(package_list_file, 'w') as f:
            for pkg in sorted(package_list):
                f.write(pkg + "\n")

def update_distro_data(distro_check_dir, datetime, d):
    """
    If distro packages list data is old then rebuild it.
    The operations has to be protected by a lock so that
    only one thread performes it at a time.
    """
    if not os.path.isdir (distro_check_dir):
        try:
            bb.note ("Making new directory: %s" % distro_check_dir)
            os.makedirs (distro_check_dir)
        except OSError:
            raise Exception('Unable to create directory %s' % (distro_check_dir))


    datetime_file = os.path.join(distro_check_dir, "build_datetime")
    saved_datetime = "_invalid_"
    import fcntl
    try:
        if not os.path.exists(datetime_file):
            open(datetime_file, 'w+').close() # touch the file so that the next open won't fail

        f = open(datetime_file, "r+")
        fcntl.lockf(f, fcntl.LOCK_EX)
        saved_datetime = f.read()
        if saved_datetime[0:8] != datetime[0:8]:
            bb.note("The build datetime did not match: saved:%s current:%s" % (saved_datetime, datetime))
            bb.note("Regenerating distro package lists")
            create_distro_packages_list(distro_check_dir, d)
            f.seek(0)
            f.write(datetime)

    except OSError as e:
        raise Exception('Unable to open timestamp: %s' % e)
    finally:
        fcntl.lockf(f, fcntl.LOCK_UN)
        f.close()

def compare_in_distro_packages_list(distro_check_dir, d):
    if not os.path.isdir(distro_check_dir):
        raise Exception("compare_in_distro_packages_list: invalid distro_check_dir passed")

    localdata = bb.data.createCopy(d)
    pkglst_dir = os.path.join(distro_check_dir, "package_lists")
    matching_distros = []
    pn = recipe_name = d.getVar('PN')
    bb.note("Checking: %s" % pn)

    if pn.find("-native") != -1:
        pnstripped = pn.split("-native")
        localdata.setVar('OVERRIDES', "pn-" + pnstripped[0] + ":" + d.getVar('OVERRIDES'))
        recipe_name = pnstripped[0]

    if pn.startswith("nativesdk-"):
        pnstripped = pn.split("nativesdk-")
        localdata.setVar('OVERRIDES', "pn-" + pnstripped[1] + ":" + d.getVar('OVERRIDES'))
        recipe_name = pnstripped[1]

    if pn.find("-cross") != -1:
        pnstripped = pn.split("-cross")
        localdata.setVar('OVERRIDES', "pn-" + pnstripped[0] + ":" + d.getVar('OVERRIDES'))
        recipe_name = pnstripped[0]

    if pn.find("-initial") != -1:
        pnstripped = pn.split("-initial")
        localdata.setVar('OVERRIDES', "pn-" + pnstripped[0] + ":" + d.getVar('OVERRIDES'))
        recipe_name = pnstripped[0]

    bb.note("Recipe: %s" % recipe_name)

    distro_exceptions = dict({"OE-Core":'OE-Core', "OpenedHand":'OpenedHand', "Intel":'Intel', "Upstream":'Upstream', "Windriver":'Windriver', "OSPDT":'OSPDT Approved', "Poky":'poky'})
    tmp = localdata.getVar('DISTRO_PN_ALIAS') or ""
    for str in tmp.split():
        if str and str.find("=") == -1 and distro_exceptions[str]:
            matching_distros.append(str)

    distro_pn_aliases = {}
    for str in tmp.split():
        if "=" in str:
            (dist, pn_alias) = str.split('=')
            distro_pn_aliases[dist.strip().lower()] = pn_alias.strip()

    for file in os.listdir(pkglst_dir):
        (distro, distro_release) = file.split("-")
        f = open(os.path.join(pkglst_dir, file), "r")
        for line in f:
            (pkg, section) = line.split(":")
            if distro.lower() in distro_pn_aliases:
                pn = distro_pn_aliases[distro.lower()]
            else:
                pn = recipe_name
            if pn == pkg:
                matching_distros.append(distro + "-" + section[:-1]) # strip the \n at the end
                f.close()
                break
        f.close()

    for item in tmp.split():
        matching_distros.append(item)
    bb.note("Matching: %s" % matching_distros)
    return matching_distros

def create_log_file(d, logname):
    logpath = d.getVar('LOG_DIR')
    bb.utils.mkdirhier(logpath)
    logfn, logsuffix = os.path.splitext(logname)
    logfile = os.path.join(logpath, "%s.%s%s" % (logfn, d.getVar('DATETIME'), logsuffix))
    if not os.path.exists(logfile):
            slogfile = os.path.join(logpath, logname)
            if os.path.exists(slogfile):
                    os.remove(slogfile)
            open(logfile, 'w+').close()
            os.symlink(logfile, slogfile)
            d.setVar('LOG_FILE', logfile)
    return logfile


def save_distro_check_result(result, datetime, result_file, d):
    pn = d.getVar('PN')
    logdir = d.getVar('LOG_DIR')
    if not logdir:
        bb.error("LOG_DIR variable is not defined, can't write the distro_check results")
        return
    bb.utils.mkdirhier(logdir)

    line = pn
    for i in result:
        line = line + "," + i
    f = open(result_file, "a")
    import fcntl
    fcntl.lockf(f, fcntl.LOCK_EX)
    f.seek(0, os.SEEK_END) # seek to the end of file
    f.write(line + "\n")
    fcntl.lockf(f, fcntl.LOCK_UN)
    f.close()
