# Common code for systemd based services.
#
# Prior to inheriting this class, recipes can define services like this:
#
# SYSTEMD_SERVICE:${PN} = "foo.service bar.socket baz@.service"
#
# and these files will be added to the main package if they exist.
#
# Alternatively this class can just be inherited and
# ${PN}.service will be added to the main package.
#
# Other variables:
# INHIBIT_SYSTEMD_RESTART_POLICY_${unit}
#    Inhibit the warning that is displayed if a service unit without a
#    restart policy is detected.
#
# SYSTEMD_SUBSTITUTIONS = "var:val:file"
#    A specification for making python style {format} string
#    substitutions where:
#      var: the format string to search for
#      val: the value to replace with
#      file: the file in which to make the substitution
#
# SYSTEMD_USER_${PN}.service = "foo"
# SYSTEMD_USER_${unit}.service = "foo"
#    The user for the unit/package.
#
# SYSTEMD_ENVIRONMENT_FILE:${PN} = "foo"
#    One or more environment files to be installed.
#
# SYSTEMD_LINK:${PN} = "tgt:name"
#    A specification for installing arbitrary links in
#    the ${systemd_system_unitdir} namespace, where:
#      tgt: the link target
#      name: the link name, relative to ${systemd_system_unitdir}
#
# SYSTEMD_OVERRIDE:${PN} = "src:dest"
#    A specification for installing unit overrides where:
#      src: the override file template
#      dest: the override install location, relative to ${systemd_system_unitdir}
#
#    Typically SYSTEMD_SUBSTITUTIONS is used to deploy a range
#    of overrides from a single template file.  To simply install
#    a single override use "foo.conf:my-service.d/foo.conf"


inherit obmc-phosphor-utils
inherit systemd
inherit useradd

_INSTALL_SD_UNITS=""
SYSTEMD_DEFAULT_TARGET ?= "multi-user.target"
envfiledir ?= "${sysconfdir}/default"

# Big ugly hack to prevent useradd.bbclass post-parse sanity checker failure.
# If there are users to be added, we'll add them in our post-parse.
# If not...there don't seem to be any ill effects...
USERADD_PACKAGES ?= " "
USERADD_PARAM:${PN} ?= ";"


def SystemdUnit(unit):
    class Unit(object):
        def __init__(self, unit):
            self.unit = unit

        def __getattr__(self, item):
            if item == 'name':
                return self.unit
            if item == 'is_activated':
                return self.unit.startswith('dbus-')
            if item == 'is_template':
                return '@.' in self.unit
            if item == 'is_instance':
                return '@' in self.unit and not self.is_template
            if item in ['is_service', 'is_target']:
                return self.unit.split('.')[-1] == item
            if item == 'base':
                cls = self.unit.split('.')[-1]
                base = self.unit.replace('dbus-', '')
                base = base.replace('.%s' % cls, '')
                if self.is_instance:
                    base = base.replace('@%s' % self.instance, '')
                if self.is_template:
                    base = base.rstrip('@')
                return base
            if item == 'instance' and self.is_instance:
                inst = self.unit.rsplit('@')[-1]
                return inst.rsplit('.')[0]
            if item == 'template' and self.is_instance:
                cls = self.unit.split('.')[-1]
                return '%s@.%s' % (self.base, cls)
            if item == 'template' and self.is_template:
                return '.'.join(self.base.split('@')[:-1])

            raise AttributeError(item)
    return Unit(unit)


def systemd_parse_unit(d, path):
    import configparser
    parser = configparser.SafeConfigParser(strict=False)
    parser.optionxform = str
    parser.read('%s' % path)
    return parser


python() {
    def check_sd_unit(d, unit):
        searchpaths = d.getVar('FILESPATH', True)
        path = bb.utils.which(searchpaths, '%s' % unit.name)
        if not os.path.isfile(path):
            # Unit does not exist in tree. Allow it to install from repo.
            # Return False here to indicate it does not exist.
            return False

        parser = systemd_parse_unit(d, path)
        inhibit = listvar_to_list(d, 'INHIBIT_SYSTEMD_RESTART_POLICY_WARNING')
        if unit.is_service and \
                not unit.is_template and \
                unit.name not in inhibit and \
                not parser.has_option('Service', 'Restart'):
            bb.warn('Systemd unit \'%s\' does not '
                'have a restart policy defined.' % unit.name)
        return True


    def add_default_subs(d, file):
        for x in [
                'base_bindir',
                'bindir',
                'sbindir',
                'libexecdir',
                'envfiledir',
                'sysconfdir',
                'localstatedir',
                'datadir',
                'SYSTEMD_DEFAULT_TARGET' ]:
            set_doappend(d, 'SYSTEMD_SUBSTITUTIONS',
                '%s:%s:%s' % (x, d.getVar(x, True), file))


    def add_sd_unit(d, unit, pkg, unit_exist):
        # Do not add unit if it does not exist in tree.
        # It will be installed from repo.
        if not unit_exist:
            return

        name = unit.name
        unit_dir = d.getVar('systemd_system_unitdir', True)
        set_doappend(d, 'SRC_URI', 'file://%s' % name)
        set_doappend(d, 'FILES:%s' % pkg, '%s/%s' % (unit_dir, name))
        set_doappend(d, '_INSTALL_SD_UNITS', name)
        add_default_subs(d, name)


    def add_sd_user(d, file, pkg):
        opts = [
            '--system',
            '--home',
            '/',
            '--no-create-home',
            '--shell /sbin/nologin',
            '--user-group']

        var = 'SYSTEMD_USER_%s' % file
        user = listvar_to_list(d, var)
        if len(user) == 0:
            var = 'SYSTEMD_USER_%s' % pkg
            user = listvar_to_list(d, var)
        if len(user) != 0:
            if len(user) != 1:
                bb.fatal('Too many users assigned to %s: \'%s\'' % (var, ' '.join(user)))

            user = user[0]
            set_doappend(d, 'SYSTEMD_SUBSTITUTIONS',
                'USER:%s:%s' % (user, file))
            if user not in d.getVar('USERADD_PARAM:%s' % pkg, True):
                set_doappend(
                    d,
                    'USERADD_PARAM:%s' % pkg,
                    '%s' % (' '.join(opts + [user])),
                    ';')
            if pkg not in d.getVar('USERADD_PACKAGES', True):
                set_doappend(d, 'USERADD_PACKAGES', pkg)


    def add_env_file(d, name, pkg):
        set_doappend(d, 'SRC_URI', 'file://%s' % name)
        set_doappend(d, 'FILES:%s' % pkg, '%s/%s' \
            % (d.getVar('envfiledir', True), name))
        set_doappend(d, '_INSTALL_ENV_FILES', name)


    def install_link(d, spec, pkg):
        tgt, dest = spec.split(':')

        set_doappend(d, 'FILES:%s' % pkg, '%s/%s' \
            % (d.getVar('systemd_system_unitdir', True), dest))
        set_doappend(d, '_INSTALL_LINKS', spec)


    def add_override(d, spec, pkg):
        tmpl, dest = spec.split(':')
        set_doappend(d, '_INSTALL_OVERRIDES', '%s' % spec)
        unit_dir = d.getVar('systemd_system_unitdir', True)
        set_doappend(d, 'FILES:%s' % pkg, '%s/%s' % (unit_dir, dest))
        add_default_subs(d, '%s' % dest)
        add_sd_user(d, '%s' % dest, pkg)


    if d.getVar('CLASSOVERRIDE', True) != 'class-target':
        return

    d.appendVarFlag('do_install', 'postfuncs', ' systemd_do_postinst')

    pn = d.getVar('PN', True)
    if d.getVar('SYSTEMD_SERVICE:%s' % pn, True) is None:
        d.setVar('SYSTEMD_SERVICE:%s' % pn, '%s.service' % pn)

    for pkg in listvar_to_list(d, 'SYSTEMD_PACKAGES'):
        svc = listvar_to_list(d, 'SYSTEMD_SERVICE:%s' % pkg)
        svc = [SystemdUnit(x) for x in svc]
        tmpl = [x.template for x in svc if x.is_instance]
        tmpl = list(set(tmpl))
        tmpl = [SystemdUnit(x) for x in tmpl]
        svc = [x for x in svc if not x.is_instance]

        for unit in tmpl + svc:
            unit_exist = check_sd_unit(d, unit)
            add_sd_unit(d, unit, pkg, unit_exist)
            add_sd_user(d, unit.name, pkg)
        for name in listvar_to_list(d, 'SYSTEMD_ENVIRONMENT_FILE:%s' % pkg):
            add_env_file(d, name, pkg)
        for spec in listvar_to_list(d, 'SYSTEMD_LINK:%s' % pkg):
            install_link(d, spec, pkg)
        for spec in listvar_to_list(d, 'SYSTEMD_OVERRIDE:%s' % pkg):
            add_override(d, spec, pkg)
}


python systemd_do_postinst() {
    def make_subs(d):
        all_subs = {}
        for spec in listvar_to_list(d, 'SYSTEMD_SUBSTITUTIONS'):
            spec, file = spec.rsplit(':', 1)
            all_subs.setdefault(file, []).append(spec)

        for f, v in all_subs.items():
            subs = dict([ x.split(':') for x in v])
            if not subs:
                continue

            path = d.getVar('D', True)
            path += d.getVar('systemd_system_unitdir', True)
            path += '/%s' % f
            with open(path, 'r') as fd:
                content = fd.read()
            with open(path, 'w+') as fd:
                try:
                    fd.write(content.format(**subs))
                except KeyError as e:
                    bb.fatal('No substitution found for %s in '
                        'file \'%s\'' % (e, f))


    def install_envs(d):
        install_dir = d.getVar('D', True)
        install_dir += d.getVar('envfiledir', True)
        searchpaths = d.getVar('FILESPATH', True)

        for f in listvar_to_list(d, '_INSTALL_ENV_FILES'):
            src = bb.utils.which(searchpaths, f)
            if not os.path.isfile(src):
                bb.fatal('Did not find SYSTEMD_ENVIRONMENT_FILE:'
                    '\'%s\'' % src)

            dest = os.path.join(install_dir, f)
            parent = os.path.dirname(dest)
            if not os.path.exists(parent):
                os.makedirs(parent)

            with open(src, 'r') as fd:
                content = fd.read()
            with open(dest, 'w+') as fd:
                fd.write(content)


    def install_links(d):
        install_dir = d.getVar('D', True)
        install_dir += d.getVar('systemd_system_unitdir', True)

        for spec in listvar_to_list(d, '_INSTALL_LINKS'):
            tgt, dest = spec.split(':')
            dest = os.path.join(install_dir, dest)
            parent = os.path.dirname(dest)
            if not os.path.exists(parent):
                os.makedirs(parent)
            os.symlink(tgt, dest)


    def install_overrides(d):
        install_dir = d.getVar('D', True)
        install_dir += d.getVar('systemd_system_unitdir', True)
        searchpaths = d.getVar('FILESPATH', True)

        for spec in listvar_to_list(d, '_INSTALL_OVERRIDES'):
            tmpl, dest = spec.split(':')
            source = bb.utils.which(searchpaths, tmpl)
            if not os.path.isfile(source):
                bb.fatal('Did not find SYSTEMD_OVERRIDE '
                    'template: \'%s\'' % source)

            dest = os.path.join(install_dir, dest)
            parent = os.path.dirname(dest)
            if not os.path.exists(parent):
                os.makedirs(parent)

            with open(source, 'r') as fd:
                content = fd.read()
            with open('%s' % dest, 'w+') as fd:
                fd.write(content)


    install_links(d)
    install_envs(d)
    install_overrides(d)
    make_subs(d)
}


do_install:append() {
        # install systemd service/socket/template files
        [ -z "${_INSTALL_SD_UNITS}" ] || \
                install -d ${D}${systemd_system_unitdir}
        for s in ${_INSTALL_SD_UNITS}; do
                install -m 0644 ${WORKDIR}/$s \
                        ${D}${systemd_system_unitdir}/$s
                sed -i -e 's,@BASE_BINDIR@,${base_bindir},g' \
                        -e 's,@BINDIR@,${bindir},g' \
                        -e 's,@SBINDIR@,${sbindir},g' \
                        -e 's,@LIBEXECDIR@,${libexecdir},g' \
                        -e 's,@LOCALSTATEDIR@,${localstatedir},g' \
                        -e 's,@DATADIR@,${datadir},g' \
                        ${D}${systemd_system_unitdir}/$s
        done
}
