#
# SPDX-License-Identifier: GPL-2.0-only
#
from abc import ABCMeta, abstractmethod
from oe.utils import execute_pre_post_process
from oe.package_manager import *
from oe.manifest import *
import oe.path
import shutil
import os
import subprocess
import re
from oe.package_manager.rpm.manifest import RpmManifest
from oe.package_manager.ipk.manifest import OpkgManifest
from oe.package_manager.deb.manifest import DpkgManifest
from oe.package_manager.rpm import RpmPkgsList
from oe.package_manager.ipk import OpkgPkgsList
from oe.package_manager.deb import DpkgPkgsList

class Rootfs(object, metaclass=ABCMeta):
    """
    This is an abstract class. Do not instantiate this directly.
    """

    def __init__(self, d, progress_reporter=None, logcatcher=None):
        self.d = d
        self.pm = None
        self.image_rootfs = self.d.getVar('IMAGE_ROOTFS')
        self.deploydir = self.d.getVar('IMGDEPLOYDIR')
        self.progress_reporter = progress_reporter
        self.logcatcher = logcatcher

        self.install_order = Manifest.INSTALL_ORDER

    @abstractmethod
    def _create(self):
        pass

    @abstractmethod
    def _get_delayed_postinsts(self):
        pass

    @abstractmethod
    def _save_postinsts(self):
        pass

    @abstractmethod
    def _log_check(self):
        pass

    def _log_check_common(self, type, match):
        # Ignore any lines containing log_check to avoid recursion, and ignore
        # lines beginning with a + since sh -x may emit code which isn't
        # actually executed, but may contain error messages
        excludes = [ 'log_check', r'^\+' ]
        if hasattr(self, 'log_check_expected_regexes'):
            excludes.extend(self.log_check_expected_regexes)
        excludes = [re.compile(x) for x in excludes]
        r = re.compile(match)
        log_path = self.d.expand("${T}/log.do_rootfs")
        messages = []
        with open(log_path, 'r') as log:
            for line in log:
                if self.logcatcher and self.logcatcher.contains(line.rstrip()):
                    continue
                for ee in excludes:
                    m = ee.search(line)
                    if m:
                        break
                if m:
                    continue

                m = r.search(line)
                if m:
                    messages.append('[log_check] %s' % line)
        if messages:
            if len(messages) == 1:
                msg = '1 %s message' % type
            else:
                msg = '%d %s messages' % (len(messages), type)
            msg = '[log_check] %s: found %s in the logfile:\n%s' % \
                (self.d.getVar('PN'), msg, ''.join(messages))
            if type == 'error':
                bb.fatal(msg)
            else:
                bb.warn(msg)

    def _log_check_warn(self):
        self._log_check_common('warning', '^(warn|Warn|WARNING:)')

    def _log_check_error(self):
        self._log_check_common('error', self.log_check_regex)

    def _insert_feed_uris(self):
        if bb.utils.contains("IMAGE_FEATURES", "package-management",
                         True, False, self.d):
            self.pm.insert_feeds_uris(self.d.getVar('PACKAGE_FEED_URIS') or "",
                self.d.getVar('PACKAGE_FEED_BASE_PATHS') or "",
                self.d.getVar('PACKAGE_FEED_ARCHS'))


    """
    The _cleanup() method should be used to clean-up stuff that we don't really
    want to end up on target. For example, in the case of RPM, the DB locks.
    The method is called, once, at the end of create() method.
    """
    @abstractmethod
    def _cleanup(self):
        pass

    def _setup_dbg_rootfs(self, dirs):
        gen_debugfs = self.d.getVar('IMAGE_GEN_DEBUGFS') or '0'
        if gen_debugfs != '1':
           return

        bb.note("  Renaming the original rootfs...")
        try:
            shutil.rmtree(self.image_rootfs + '-orig')
        except:
            pass
        os.rename(self.image_rootfs, self.image_rootfs + '-orig')

        bb.note("  Creating debug rootfs...")
        bb.utils.mkdirhier(self.image_rootfs)

        bb.note("  Copying back package database...")
        for dir in dirs:
            if not os.path.isdir(self.image_rootfs + '-orig' + dir):
                continue
            bb.utils.mkdirhier(self.image_rootfs + os.path.dirname(dir))
            shutil.copytree(self.image_rootfs + '-orig' + dir, self.image_rootfs + dir, symlinks=True)

        # Copy files located in /usr/lib/debug or /usr/src/debug
        for dir in ["/usr/lib/debug", "/usr/src/debug"]:
            src = self.image_rootfs + '-orig' + dir
            if os.path.exists(src):
                dst = self.image_rootfs + dir
                bb.utils.mkdirhier(os.path.dirname(dst))
                shutil.copytree(src, dst)

        # Copy files with suffix '.debug' or located in '.debug' dir.
        for root, dirs, files in os.walk(self.image_rootfs + '-orig'):
            relative_dir = root[len(self.image_rootfs + '-orig'):]
            for f in files:
                if f.endswith('.debug') or '/.debug' in relative_dir:
                    bb.utils.mkdirhier(self.image_rootfs + relative_dir)
                    shutil.copy(os.path.join(root, f),
                                self.image_rootfs + relative_dir)

        bb.note("  Install complementary '*-dbg' packages...")
        self.pm.install_complementary('*-dbg')

        if self.d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
            bb.note("  Install complementary '*-src' packages...")
            self.pm.install_complementary('*-src')

        """
        Install additional debug packages. Possibility to install additional packages,
        which are not automatically installed as complementary package of
        standard one, e.g. debug package of static libraries.
        """
        extra_debug_pkgs = self.d.getVar('IMAGE_INSTALL_DEBUGFS')
        if extra_debug_pkgs:
            bb.note("  Install extra debug packages...")
            self.pm.install(extra_debug_pkgs.split(), True)

        bb.note("  Rename debug rootfs...")
        try:
            shutil.rmtree(self.image_rootfs + '-dbg')
        except:
            pass
        os.rename(self.image_rootfs, self.image_rootfs + '-dbg')

        bb.note("  Restoreing original rootfs...")
        os.rename(self.image_rootfs + '-orig', self.image_rootfs)

    def _exec_shell_cmd(self, cmd):
        fakerootcmd = self.d.getVar('FAKEROOT')
        if fakerootcmd is not None:
            exec_cmd = [fakerootcmd, cmd]
        else:
            exec_cmd = cmd

        try:
            subprocess.check_output(exec_cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            return("Command '%s' returned %d:\n%s" % (e.cmd, e.returncode, e.output))

        return None

    def create(self):
        bb.note("###### Generate rootfs #######")
        pre_process_cmds = self.d.getVar("ROOTFS_PREPROCESS_COMMAND")
        post_process_cmds = self.d.getVar("ROOTFS_POSTPROCESS_COMMAND")
        rootfs_post_install_cmds = self.d.getVar('ROOTFS_POSTINSTALL_COMMAND')

        bb.utils.mkdirhier(self.image_rootfs)

        bb.utils.mkdirhier(self.deploydir)

        execute_pre_post_process(self.d, pre_process_cmds)

        if self.progress_reporter:
            self.progress_reporter.next_stage()

        # call the package manager dependent create method
        self._create()

        sysconfdir = self.image_rootfs + self.d.getVar('sysconfdir')
        bb.utils.mkdirhier(sysconfdir)
        with open(sysconfdir + "/version", "w+") as ver:
            ver.write(self.d.getVar('BUILDNAME') + "\n")

        execute_pre_post_process(self.d, rootfs_post_install_cmds)

        self.pm.run_intercepts()

        execute_pre_post_process(self.d, post_process_cmds)

        if self.progress_reporter:
            self.progress_reporter.next_stage()

        if bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
                         True, False, self.d):
            delayed_postinsts = self._get_delayed_postinsts()
            if delayed_postinsts is not None:
                bb.fatal("The following packages could not be configured "
                         "offline and rootfs is read-only: %s" %
                         delayed_postinsts)

        if self.d.getVar('USE_DEVFS') != "1":
            self._create_devfs()

        self._uninstall_unneeded()

        if self.progress_reporter:
            self.progress_reporter.next_stage()

        self._insert_feed_uris()

        self._run_ldconfig()

        if self.d.getVar('USE_DEPMOD') != "0":
            self._generate_kernel_module_deps()

        self._cleanup()
        self._log_check()

        if self.progress_reporter:
            self.progress_reporter.next_stage()


    def _uninstall_unneeded(self):
        # Remove unneeded init script symlinks
        delayed_postinsts = self._get_delayed_postinsts()
        if delayed_postinsts is None:
            if os.path.exists(self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/init.d/run-postinsts")):
                self._exec_shell_cmd(["update-rc.d", "-f", "-r",
                                      self.d.getVar('IMAGE_ROOTFS'),
                                      "run-postinsts", "remove"])

        image_rorfs = bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
                                        True, False, self.d)
        image_rorfs_force = self.d.getVar('FORCE_RO_REMOVE')

        if image_rorfs or image_rorfs_force == "1":
            # Remove components that we don't need if it's a read-only rootfs
            unneeded_pkgs = self.d.getVar("ROOTFS_RO_UNNEEDED").split()
            pkgs_installed = image_list_installed_packages(self.d)
            # Make sure update-alternatives is removed last. This is
            # because its database has to available while uninstalling
            # other packages, allowing alternative symlinks of packages
            # to be uninstalled or to be managed correctly otherwise.
            provider = self.d.getVar("VIRTUAL-RUNTIME_update-alternatives")
            pkgs_to_remove = sorted([pkg for pkg in pkgs_installed if pkg in unneeded_pkgs], key=lambda x: x == provider)

            # update-alternatives provider is removed in its own remove()
            # call because all package managers do not guarantee the packages
            # are removed in the order they given in the list (which is
            # passed to the command line). The sorting done earlier is
            # utilized to implement the 2-stage removal.
            if len(pkgs_to_remove) > 1:
                self.pm.remove(pkgs_to_remove[:-1], False)
            if len(pkgs_to_remove) > 0:
                self.pm.remove([pkgs_to_remove[-1]], False)

        if delayed_postinsts:
            self._save_postinsts()
            if image_rorfs:
                bb.warn("There are post install scripts "
                        "in a read-only rootfs")

        post_uninstall_cmds = self.d.getVar("ROOTFS_POSTUNINSTALL_COMMAND")
        execute_pre_post_process(self.d, post_uninstall_cmds)

        runtime_pkgmanage = bb.utils.contains("IMAGE_FEATURES", "package-management",
                                              True, False, self.d)
        if not runtime_pkgmanage:
            # Remove the package manager data files
            self.pm.remove_packaging_data()

    def _run_ldconfig(self):
        if self.d.getVar('LDCONFIGDEPEND'):
            bb.note("Executing: ldconfig -r " + self.image_rootfs + " -c new -v -X")
            self._exec_shell_cmd(['ldconfig', '-r', self.image_rootfs, '-c',
                                  'new', '-v', '-X'])

    def _check_for_kernel_modules(self, modules_dir):
        for root, dirs, files in os.walk(modules_dir, topdown=True):
            for name in files:
                found_ko = name.endswith(".ko")
                if found_ko:
                    return found_ko
        return False

    def _generate_kernel_module_deps(self):
        modules_dir = os.path.join(self.image_rootfs, 'lib', 'modules')
        # if we don't have any modules don't bother to do the depmod
        if not self._check_for_kernel_modules(modules_dir):
            bb.note("No Kernel Modules found, not running depmod")
            return

        kernel_abi_ver_file = oe.path.join(self.d.getVar('PKGDATA_DIR'), "kernel-depmod",
                                           'kernel-abiversion')
        if not os.path.exists(kernel_abi_ver_file):
            bb.fatal("No kernel-abiversion file found (%s), cannot run depmod, aborting" % kernel_abi_ver_file)

        kernel_ver = open(kernel_abi_ver_file).read().strip(' \n')
        versioned_modules_dir = os.path.join(self.image_rootfs, modules_dir, kernel_ver)

        bb.utils.mkdirhier(versioned_modules_dir)

        self._exec_shell_cmd(['depmodwrapper', '-a', '-b', self.image_rootfs, kernel_ver])

    """
    Create devfs:
    * IMAGE_DEVICE_TABLE is the old name to an absolute path to a device table file
    * IMAGE_DEVICE_TABLES is a new name for a file, or list of files, seached
      for in the BBPATH
    If neither are specified then the default name of files/device_table-minimal.txt
    is searched for in the BBPATH (same as the old version.)
    """
    def _create_devfs(self):
        devtable_list = []
        devtable = self.d.getVar('IMAGE_DEVICE_TABLE')
        if devtable is not None:
            devtable_list.append(devtable)
        else:
            devtables = self.d.getVar('IMAGE_DEVICE_TABLES')
            if devtables is None:
                devtables = 'files/device_table-minimal.txt'
            for devtable in devtables.split():
                devtable_list.append("%s" % bb.utils.which(self.d.getVar('BBPATH'), devtable))

        for devtable in devtable_list:
            self._exec_shell_cmd(["makedevs", "-r",
                                  self.image_rootfs, "-D", devtable])


def get_class_for_type(imgtype):
    from oe.package_manager.rpm.rootfs import RpmRootfs
    from oe.package_manager.ipk.rootfs import OpkgRootfs
    from oe.package_manager.deb.rootfs import DpkgRootfs
    return {"rpm": RpmRootfs,
            "ipk": OpkgRootfs,
            "deb": DpkgRootfs}[imgtype]

def variable_depends(d, manifest_dir=None):
    img_type = d.getVar('IMAGE_PKGTYPE')
    cls = get_class_for_type(img_type)
    return cls._depends_list()

def create_rootfs(d, manifest_dir=None, progress_reporter=None, logcatcher=None):
    env_bkp = os.environ.copy()

    from oe.package_manager.rpm.rootfs import RpmRootfs
    from oe.package_manager.ipk.rootfs import OpkgRootfs
    from oe.package_manager.deb.rootfs import DpkgRootfs
    img_type = d.getVar('IMAGE_PKGTYPE')
    if img_type == "rpm":
        RpmRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
    elif img_type == "ipk":
        OpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
    elif img_type == "deb":
        DpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()

    os.environ.clear()
    os.environ.update(env_bkp)


def image_list_installed_packages(d, rootfs_dir=None):
    if not rootfs_dir:
        rootfs_dir = d.getVar('IMAGE_ROOTFS')

    img_type = d.getVar('IMAGE_PKGTYPE')
    if img_type == "rpm":
        return RpmPkgsList(d, rootfs_dir).list_pkgs()
    elif img_type == "ipk":
        return OpkgPkgsList(d, rootfs_dir, d.getVar("IPKGCONF_TARGET")).list_pkgs()
    elif img_type == "deb":
        return DpkgPkgsList(d, rootfs_dir).list_pkgs()

if __name__ == "__main__":
    """
    We should be able to run this as a standalone script, from outside bitbake
    environment.
    """
    """
    TBD
    """
