#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# === This file is part of Calamares - <http://github.com/calamares> ===
#
#   Copyright 2014 - 2016, Philip Müller <philm@manjaro.org>
#   Copyright 2016, Artoo <artoo@manjaro.org>
#   Copyright 2018, Artoo <artoo@artixlinux.org>
#
#   Calamares 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 3 of the License, or
#   (at your option) any later version.
#
#   Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.


from os.path import join, exists

import libcalamares
from libcalamares.utils import target_env_call


import gettext
_ = gettext.translation("calamares-python",
                        localedir=libcalamares.utils.gettext_path(),
                        languages=libcalamares.utils.gettext_languages(),
                        fallback=True).gettext


def pretty_name():
    return _("Configure user services")


def terminate(proc):
    """Send SIGKILL to the given proccess
    """
    target_env_call(['killall', '-9', proc])

def sedFile(pattern, file):
    """Sed the given file with the given pattern
    """
    target_env_call(["sed", "-e", pattern, "-i", file])

def configure(initsys):
    """Configure the services
    """
    if initsys == "openrc":
        exp = 's|^.*keymap=.*|keymap="{}"|'.format(
            libcalamares.globalstorage.value("keyboardLayout")
        )
        sedFile(exp, "/etc/conf.d/keymaps")

def fix_btrfs_boot(root):
    if exists(join(root, "usr/bin/dd")):

        ec = target_env_call(["sh", "-c", 'mkdir -p /tmp/vmlinuz-hack && mv /boot/vmlinuz-* /tmp/vmlinuz-hack/ && find /tmp/vmlinuz-hack/ -maxdepth 1 -type f -exec sh -c \'dd if="$1" of="/boot/$(basename "$1")"\' sh {} \;'])

        if ec != 0:
            libcalamares.utils.warning(
                "dd {} call in chroot returned error code {}".format("/boot", ec)
            )

        if exists(join(root, "boot/intel-ucode.img")):
            ec = target_env_call(["sh", "-c", 'mkdir -p /tmp/intel-hack && mv /boot/intel-ucode.img /tmp/intel-hack/ && find /tmp/intel-hack/ -maxdepth 1 -type f -exec sh -c \'dd if="$1" of="/boot/$(basename "$1")"\' sh {} \;'])

            if ec != 0:
                libcalamares.utils.warning(
                "dd {} call in chroot returned error code {}".format("/boot", ec)
            )

        if exists(join(root, "boot/amd-ucode.img")):
            ec = target_env_call(["sh", "-c", 'mkdir -p /tmp/amd-hack && mv /boot/amd-ucode.img /tmp/amd-hack/ && find /tmp/amd-hack/ -maxdepth 1 -type f -exec sh -c \'dd if="$1" of="/boot/$(basename "$1")"\' sh {} \;'])

            if ec != 0:
                libcalamares.utils.warning(
                "dd {} call in chroot returned error code {}".format("/boot", ec)
            )


def manage_services(services, initsys, root):
    """
    For each entry in @p services, run "<command> <action> <name>",
    where each service is a mapping of service name, action, and a flag.

    Returns a failure message, or None if this was successful.
    """

    username = libcalamares.globalstorage.value("username")

    userhome = "/home/" + username

    owner = username + ":" + username

    if initsys == "openrc":

        dir_path = userhome + "/.config/rc/runlevels/default"

        ec = target_env_call(["mkdir", "-p", dir_path])

        if ec != 0:
            libcalamares.utils.warning(
                "create dir {} call in chroot returned error code {}".format(dir_path, ec)
            )

    elif initsys == "dinit":

        dir_path = userhome + "/.config/dinit.d/boot.d"

        ec = target_env_call(["mkdir", "-p", dir_path])

        if ec != 0:
            libcalamares.utils.warning(
                "create dir {} call in chroot returned error code {}".format(dir_path, ec)
            )

    for sv in services:
        if isinstance(sv, str):
            name = sv
            action = "enable"
        else:
            if "name" not in sv:
                libcalamares.utils.error("The key 'name' is missing from the mapping {_sv!s}. Continuing to the next service.".format(_sv=str(sv)))
                continue
            name = sv["name"]
            action = sv.get("action", "enable")

        if initsys == "openrc":

            svhome = userhome + "/.config/rc"

            src = "/etc/user/init.d/" + name
            urlvl = svhome + "/runlevels/default/"
            dest = urlvl + name

            if action == "enable":

                if exists(join(root, src)):

                    ec = target_env_call(["ln", "-s", src, dest])

                    if ec != 0:
                        libcalamares.utils.warning(
                            "service {} call in chroot returned error code {}".format(action, ec)
                        )


                    ec = target_env_call(["chown", "-R", owner, svhome ])

                    if ec != 0:
                        libcalamares.utils.warning(
                            "chown {} call in chroot returned error code {}".format(svhome, ec)
                        )

        elif initsys == "dinit":

            svhome = userhome + "/.config/dinit.d"

            src = "/etc/dinit.d/user/" + name
            ubdir = svhome + "/boot.d/"
            dest = ubdir + name

            if action == "enable":

                if exists(join(root, src)):

                    ec = target_env_call(["ln", "-s", src, dest])

                    if ec != 0:
                        libcalamares.utils.warning(
                            "service {} call in chroot returned error code {}".format(action, ec)
                        )

                    ec = target_env_call(["chown", "-R", owner, svhome])

                    if ec != 0:
                        libcalamares.utils.warning(
                            "chown {} call in chroot returned error code {}".format(svhome, ec)
                        )


def run():
    """
    Misc postinstall configurations
    """

    install_root = libcalamares.globalstorage.value("rootMountPoint")

    initsys = libcalamares.job.configuration["initsys"]

    userservices = libcalamares.job.configuration.get("user-services", [])

    partitions = libcalamares.globalstorage.value("partitions")

    configure(initsys)

    has_btrfs = False

    for partition in partitions:
        if partition["fs"] == "btrfs":
            has_btrfs = True

    if has_btrfs:
        fix_btrfs_boot(install_root)

    # terminate('gpg-agent')

    r = manage_services(userservices, initsys, install_root)

    if r is not None:
        return r
