from __future__ import absolute_import, unicode_literals
import os
import shutil
from .log import log
from services import executor
from util.string_util import strip_whitespace, get_file_timestamp
from util.file_util import get_all_filepaths, write_to_file


ROOT_USER = "root"


def remove(path, is_dir=True, force=True, **kwargs):
    command = ["rm"]
    if is_dir:
        command.append("-r")
    if force:
        command.append("-f")
    command.append(path)
    executor.execute(command, **kwargs)


def remove_all_in_directory(path):
    """Remove all files and subdirs, but not the directory (path) itself."""
    for files in os.listdir(path):
        p = os.path.join(path, files)
        try:
            shutil.rmtree(p)
        except OSError:
            os.remove(p)


def copy(source, dest, is_dir=True, **kwargs):
    command = ["cp", "-v"]
    if is_dir:
        command.append("-r")
    command.append(source)
    command.append(dest)
    executor.execute(command, **kwargs)


def make_backup(source, **kwargs):
    if os.path.exists(source):
        dest = source + "." + get_file_timestamp() + ".bak"
        command = ["cp", "-a", source, dest]
        executor.executeSudo(command, **kwargs)
        return dest
    else:
        return None


def make_directory(path, build_all=True, **kwargs):
    command = ["mkdir"]
    if build_all:
        command.append("-p")
    command.append(path)
    executor.execute(command, **kwargs)


def move(source, dest, **kwargs):
    executor.execute(["mv", "-v", source, dest], **kwargs)


def chmod(path, mod, is_dir=True, **kwargs):
    command = ["chmod"]
    if is_dir:
        command.append("-R")
    command.append(str(mod))
    command.append(path)
    executor.execute(command, throw_on_error=False, **kwargs)


def chown(path, owner, group=None, is_dir=True, **kwargs):
    command = ["chown"]
    if is_dir:
        command.append("-R")
    if group:
        owner = owner + ":" + group
    else:
        owner = owner + ":"
    command.append(owner)
    command.append(path)
    executor.execute(command, throw_on_error=False, **kwargs)


def download_file(url, dest, **kwargs):
    command = ["wget", "--no-check-certificate", url, "-O", dest]
    executor.execute(command, **kwargs)


def untar(path, **kwargs):
    command = ["tar", "-xzvf", path]
    executor.execute(command, **kwargs)


def nproc():
    out, _, _ = executor.execute(["nproc"], throw_on_error=False)
    out = strip_whitespace(out)
    if len(out) == 0:
        out = "1"
    return out


def replace_in_all_files_with_sed(path, search_replace_dict):
    """
    Replaces strings in all files in a directory
    :param str path: the path to the file you want to replace in
    :param dict[str,str] search_replace_dict: the dict for replacing
    """
    files = get_all_filepaths(path)
    for filepath in files:
        for key, val in search_replace_dict.items():
            executor.execute(["sed", "-i", "s|" + key + "|" + val + "|g", filepath])


def merge_properties(first_file, second_file):
    """
    Merges the second_file into the first_file. Note that the first file is
    overwritten, so make sure to back it up before calling this function.
    :param str first_file: the first properties file
    :param str second_file: the second properties file
    """
    out, err, rc = executor.execute(
        ["awk", "-F=", "/^$/ || $1 ~ /^#/ || !($1 in settings) {settings[$1] = $2; print}",
        first_file, second_file])
    if out is not None and out != "" and rc == 0:
        write_to_file(first_file, out)


def add_user_to_group(user, group):
    """
    If user is not in group then add it. Returns True if added, False otherwise
    :param str user: linux user
    :param str group: linux group
    :rtype: bool
    """
    ret = False
    out, err, rc = executor.execute(["groups", user], user=user, throw_on_error=False)
    if rc == 0:
        group_tmp = ' ' + group + ' '
        if group_tmp not in out:
            log.info("Adding user '{}' to group '{}'...".format(user, group))
            _, _, rc = executor.executeSudo(["usermod", "-a", "-G", group, user])
            if rc == 0:
                log.info("Successfully added the user to the group.")
                ret = True
            else:
                log.error("Failed adding the user to the group.")
    return ret


def program_exists(program_name, path=None):
    return shutil.which(program_name, path=path) is not None


def sudo_remove(path, is_dir=True, force=True, **kwargs):
    remove(path, is_dir, force, user=ROOT_USER, **kwargs)


def sudo_copy(source, dest, is_dir=True, **kwargs):
    copy(source, dest, is_dir, user=ROOT_USER, **kwargs)


def sudo_chown(path, owner, group=None, is_dir=True, **kwargs):
    chown(path, owner, group, is_dir, user=ROOT_USER, **kwargs)


def sudo_chmod(path, mod, is_dir=True, **kwargs):
    chmod(path, mod, is_dir, user=ROOT_USER, **kwargs)


def sudo_move(source, dest, **kwargs):
    move(source, dest, user=ROOT_USER, **kwargs)


def sudo_mkdir(dest, build_all=True, **kwargs):
    make_directory(dest, build_all, user=ROOT_USER, **kwargs)
