#!/usr/bin/env python

# Copyright (C) 2009 by Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

import argparse
import datetime
import fnmatch
import os
from collections import defaultdict
import re
import subprocess
import sys

INFRA_RE = re.compile("\$\(eval \$\(([a-z-]*)-package\)\)")


class Package:
    all_licenses = list()
    all_license_files = list()
    all_versions = dict()

    def __init__(self, name, path):
        self.name = name
        self.path = path
        self.infras = None
        self.has_license = False
        self.has_license_files = False
        self.has_hash = False
        self.patch_count = 0
        self.warnings = 0
        self.current_version = None

    def pkgvar(self):
        return self.name.upper().replace("-", "_")

    def set_infra(self):
        """
        Fills in the .infras field
        """
        self.infras = list()
        with open(self.path, 'r') as f:
            lines = f.readlines()
            for l in lines:
                match = INFRA_RE.match(l)
                if not match:
                    continue
                infra = match.group(1)
                if infra.startswith("host-"):
                    self.infras.append(("host", infra[5:]))
                else:
                    self.infras.append(("target", infra))

    def set_license(self):
        """
        Fills in the .has_license and .has_license_files fields
        """
        var = self.pkgvar()
        if var in self.all_licenses:
            self.has_license = True
        if var in self.all_license_files:
            self.has_license_files = True

    def set_hash_info(self):
        """
        Fills in the .has_hash field
        """
        hashpath = self.path.replace(".mk", ".hash")
        self.has_hash = os.path.exists(hashpath)

    def set_patch_count(self):
        """
        Fills in the .patch_count field
        """
        self.patch_count = 0
        pkgdir = os.path.dirname(self.path)
        for subdir, _, _ in os.walk(pkgdir):
            self.patch_count += len(fnmatch.filter(os.listdir(subdir), '*.patch'))

    def set_current_version(self):
        """
        Fills in the .current_version field
        """
        var = self.pkgvar()
        if var in self.all_versions:
            self.current_version = self.all_versions[var]

    def set_check_package_warnings(self):
        """
        Fills in the .warnings field
        """
        cmd = ["./utils/check-package"]
        pkgdir = os.path.dirname(self.path)
        for root, dirs, files in os.walk(pkgdir):
            for f in files:
                if f.endswith(".mk") or f.endswith(".hash") or f == "Config.in" or f == "Config.in.host":
                    cmd.append(os.path.join(root, f))
        o = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[1]
        lines = o.splitlines()
        for line in lines:
            m = re.match("^([0-9]*) warnings generated", line)
            if m:
                self.warnings = int(m.group(1))
                return

    def __eq__(self, other):
        return self.path == other.path

    def __lt__(self, other):
        return self.path < other.path

    def __str__(self):
        return "%s (path='%s', license='%s', license_files='%s', hash='%s', patches=%d)" % \
            (self.name, self.path, self.has_license, self.has_license_files, self.has_hash, self.patch_count)


def get_pkglist(npackages, package_list):
    """
    Builds the list of Buildroot packages, returning a list of Package
    objects. Only the .name and .path fields of the Package object are
    initialized.

    npackages: limit to N packages
    package_list: limit to those packages in this list
    """
    WALK_USEFUL_SUBDIRS = ["boot", "linux", "package", "toolchain"]
    WALK_EXCLUDES = ["boot/common.mk",
                     "linux/linux-ext-.*.mk",
                     "package/freescale-imx/freescale-imx.mk",
                     "package/gcc/gcc.mk",
                     "package/gstreamer/gstreamer.mk",
                     "package/gstreamer1/gstreamer1.mk",
                     "package/gtk2-themes/gtk2-themes.mk",
                     "package/matchbox/matchbox.mk",
                     "package/opengl/opengl.mk",
                     "package/qt5/qt5.mk",
                     "package/x11r7/x11r7.mk",
                     "package/doc-asciidoc.mk",
                     "package/pkg-.*.mk",
                     "package/nvidia-tegra23/nvidia-tegra23.mk",
                     "toolchain/toolchain-external/pkg-toolchain-external.mk",
                     "toolchain/toolchain-external/toolchain-external.mk",
                     "toolchain/toolchain.mk",
                     "toolchain/helpers.mk",
                     "toolchain/toolchain-wrapper.mk"]
    packages = list()
    count = 0
    for root, dirs, files in os.walk("."):
        rootdir = root.split("/")
        if len(rootdir) < 2:
            continue
        if rootdir[1] not in WALK_USEFUL_SUBDIRS:
            continue
        for f in files:
            if not f.endswith(".mk"):
                continue
            # Strip ending ".mk"
            pkgname = f[:-3]
            if package_list and pkgname not in package_list:
                continue
            pkgpath = os.path.join(root, f)
            skip = False
            for exclude in WALK_EXCLUDES:
                # pkgpath[2:] strips the initial './'
                if re.match(exclude, pkgpath[2:]):
                    skip = True
                    continue
            if skip:
                continue
            p = Package(pkgname, pkgpath)
            packages.append(p)
            count += 1
            if npackages and count == npackages:
                return packages
    return packages


def package_init_make_info():
    # Licenses
    o = subprocess.check_output(["make", "BR2_HAVE_DOT_CONFIG=y",
                                 "-s", "printvars", "VARS=%_LICENSE"])
    for l in o.splitlines():
        # Get variable name and value
        pkgvar, value = l.split("=")

        # If present, strip HOST_ from variable name
        if pkgvar.startswith("HOST_"):
            pkgvar = pkgvar[5:]

        # Strip _LICENSE
        pkgvar = pkgvar[:-8]

        # If value is "unknown", no license details available
        if value == "unknown":
            continue
        Package.all_licenses.append(pkgvar)

    # License files
    o = subprocess.check_output(["make", "BR2_HAVE_DOT_CONFIG=y",
                                 "-s", "printvars", "VARS=%_LICENSE_FILES"])
    for l in o.splitlines():
        # Get variable name and value
        pkgvar, value = l.split("=")

        # If present, strip HOST_ from variable name
        if pkgvar.startswith("HOST_"):
            pkgvar = pkgvar[5:]

        if pkgvar.endswith("_MANIFEST_LICENSE_FILES"):
            continue

        # Strip _LICENSE_FILES
        pkgvar = pkgvar[:-14]

        Package.all_license_files.append(pkgvar)

    # Version
    o = subprocess.check_output(["make", "BR2_HAVE_DOT_CONFIG=y",
                                 "-s", "printvars", "VARS=%_VERSION"])

    # We process first the host package VERSION, and then the target
    # package VERSION. This means that if a package exists in both
    # target and host variants, with different version numbers
    # (unlikely), we'll report the target version number.
    version_list = o.splitlines()
    version_list = [x for x in version_list if x.startswith("HOST_")] + \
                   [x for x in version_list if not x.startswith("HOST_")]
    for l in version_list:
        # Get variable name and value
        pkgvar, value = l.split("=")

        # If present, strip HOST_ from variable name
        if pkgvar.startswith("HOST_"):
            pkgvar = pkgvar[5:]

        if pkgvar.endswith("_DL_VERSION"):
            continue

        # Strip _VERSION
        pkgvar = pkgvar[:-8]

        Package.all_versions[pkgvar] = value


def calculate_stats(packages):
    stats = defaultdict(int)
    for pkg in packages:
        # If packages have multiple infra, take the first one. For the
        # vast majority of packages, the target and host infra are the
        # same. There are very few packages that use a different infra
        # for the host and target variants.
        if len(pkg.infras) > 0:
            infra = pkg.infras[0][1]
            stats["infra-%s" % infra] += 1
        else:
            stats["infra-unknown"] += 1
        if pkg.has_license:
            stats["license"] += 1
        else:
            stats["no-license"] += 1
        if pkg.has_license_files:
            stats["license-files"] += 1
        else:
            stats["no-license-files"] += 1
        if pkg.has_hash:
            stats["hash"] += 1
        else:
            stats["no-hash"] += 1
        stats["patches"] += pkg.patch_count
    return stats


html_header = """
<head>
<script src=\"https://www.kryogenix.org/code/browser/sorttable/sorttable.js\"></script>
<style type=\"text/css\">
table {
  width: 100%;
}
td {
  border: 1px solid black;
}
td.centered {
  text-align: center;
}
td.wrong {
  background: #ff9a69;
}
td.correct {
  background: #d2ffc4;
}
td.nopatches {
  background: #d2ffc4;
}
td.somepatches {
  background: #ffd870;
}
td.lotsofpatches {
  background: #ff9a69;
}
</style>
<title>Statistics of Buildroot packages</title>
</head>

<a href=\"#results\">Results</a><br/>

<p id=\"sortable_hint\"></p>
"""


html_footer = """
</body>
<script>
if (typeof sorttable === \"object\") {
  document.getElementById(\"sortable_hint\").innerHTML =
  \"hint: the table can be sorted by clicking the column headers\"
}
</script>
</html>
"""


def infra_str(infra_list):
    if not infra_list:
        return "Unknown"
    elif len(infra_list) == 1:
        return "<b>%s</b><br/>%s" % (infra_list[0][1], infra_list[0][0])
    elif infra_list[0][1] == infra_list[1][1]:
        return "<b>%s</b><br/>%s + %s" % \
            (infra_list[0][1], infra_list[0][0], infra_list[1][0])
    else:
        return "<b>%s</b> (%s)<br/><b>%s</b> (%s)" % \
            (infra_list[0][1], infra_list[0][0],
             infra_list[1][1], infra_list[1][0])


def boolean_str(b):
    if b:
        return "Yes"
    else:
        return "No"


def dump_html_pkg(f, pkg):
    f.write(" <tr>\n")
    f.write("  <td>%s</td>\n" % pkg.path[2:])

    # Patch count
    td_class = ["centered"]
    if pkg.patch_count == 0:
        td_class.append("nopatches")
    elif pkg.patch_count < 5:
        td_class.append("somepatches")
    else:
        td_class.append("lotsofpatches")
    f.write("  <td class=\"%s\">%s</td>\n" %
            (" ".join(td_class), str(pkg.patch_count)))

    # Infrastructure
    infra = infra_str(pkg.infras)
    td_class = ["centered"]
    if infra == "Unknown":
        td_class.append("wrong")
    else:
        td_class.append("correct")
    f.write("  <td class=\"%s\">%s</td>\n" %
            (" ".join(td_class), infra_str(pkg.infras)))

    # License
    td_class = ["centered"]
    if pkg.has_license:
        td_class.append("correct")
    else:
        td_class.append("wrong")
    f.write("  <td class=\"%s\">%s</td>\n" %
            (" ".join(td_class), boolean_str(pkg.has_license)))

    # License files
    td_class = ["centered"]
    if pkg.has_license_files:
        td_class.append("correct")
    else:
        td_class.append("wrong")
    f.write("  <td class=\"%s\">%s</td>\n" %
            (" ".join(td_class), boolean_str(pkg.has_license_files)))

    # Hash
    td_class = ["centered"]
    if pkg.has_hash:
        td_class.append("correct")
    else:
        td_class.append("wrong")
    f.write("  <td class=\"%s\">%s</td>\n" %
            (" ".join(td_class), boolean_str(pkg.has_hash)))

    # Current version
    if len(pkg.current_version) > 20:
        current_version = pkg.current_version[:20] + "..."
    else:
        current_version = pkg.current_version
    f.write("  <td class=\"centered\">%s</td>\n" % current_version)

    # Warnings
    td_class = ["centered"]
    if pkg.warnings == 0:
        td_class.append("correct")
    else:
        td_class.append("wrong")
    f.write("  <td class=\"%s\">%d</td>\n" %
            (" ".join(td_class), pkg.warnings))

    f.write(" </tr>\n")


def dump_html_all_pkgs(f, packages):
    f.write("""
<table class=\"sortable\">
<tr>
<td>Package</td>
<td class=\"centered\">Patch count</td>
<td class=\"centered\">Infrastructure</td>
<td class=\"centered\">License</td>
<td class=\"centered\">License files</td>
<td class=\"centered\">Hash file</td>
<td class=\"centered\">Current version</td>
<td class=\"centered\">Warnings</td>
</tr>
""")
    for pkg in sorted(packages):
        dump_html_pkg(f, pkg)
    f.write("</table>")


def dump_html_stats(f, stats):
    f.write("<a id=\"results\"></a>\n")
    f.write("<table>\n")
    infras = [infra[6:] for infra in stats.keys() if infra.startswith("infra-")]
    for infra in infras:
        f.write(" <tr><td>Packages using the <i>%s</i> infrastructure</td><td>%s</td></tr>\n" %
                (infra, stats["infra-%s" % infra]))
    f.write(" <tr><td>Packages having license information</td><td>%s</td></tr>\n" %
            stats["license"])
    f.write(" <tr><td>Packages not having license information</td><td>%s</td></tr>\n" %
            stats["no-license"])
    f.write(" <tr><td>Packages having license files information</td><td>%s</td></tr>\n" %
            stats["license-files"])
    f.write(" <tr><td>Packages not having license files information</td><td>%s</td></tr>\n" %
            stats["no-license-files"])
    f.write(" <tr><td>Packages having a hash file</td><td>%s</td></tr>\n" %
            stats["hash"])
    f.write(" <tr><td>Packages not having a hash file</td><td>%s</td></tr>\n" %
            stats["no-hash"])
    f.write(" <tr><td>Total number of patches</td><td>%s</td></tr>\n" %
            stats["patches"])
    f.write("</table>\n")


def dump_gen_info(f):
    # Updated on Mon Feb 19 08:12:08 CET 2018, Git commit aa77030b8f5e41f1c53eb1c1ad664b8c814ba032
    o = subprocess.check_output(["git", "log", "master", "-n", "1", "--pretty=format:%H"])
    git_commit = o.splitlines()[0]
    f.write("<p><i>Updated on %s, git commit %s</i></p>\n" %
            (str(datetime.datetime.utcnow()), git_commit))


def dump_html(packages, stats, output):
    with open(output, 'w') as f:
        f.write(html_header)
        dump_html_all_pkgs(f, packages)
        dump_html_stats(f, stats)
        dump_gen_info(f)
        f.write(html_footer)


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', dest='output', action='store', required=True,
                        help='HTML output file')
    parser.add_argument('-n', dest='npackages', type=int, action='store',
                        help='Number of packages')
    parser.add_argument('-p', dest='packages', action='store',
                        help='List of packages (comma separated)')
    return parser.parse_args()


def __main__():
    args = parse_args()
    if args.npackages and args.packages:
        print("ERROR: -n and -p are mutually exclusive")
        sys.exit(1)
    if args.packages:
        package_list = args.packages.split(",")
    else:
        package_list = None
    print("Build package list ...")
    packages = get_pkglist(args.npackages, package_list)
    print("Getting package make info ...")
    package_init_make_info()
    print("Getting package details ...")
    for pkg in packages:
        pkg.set_infra()
        pkg.set_license()
        pkg.set_hash_info()
        pkg.set_patch_count()
        pkg.set_check_package_warnings()
        pkg.set_current_version()
    print("Calculate stats")
    stats = calculate_stats(packages)
    print("Write HTML")
    dump_html(packages, stats, args.output)


__main__()
