#!/usr/bin/env python3
import configparser
import getpass
import os
import shutil
import subprocess
import sys

import pkg_resources

try:
    import raveberry

    raveberry_directory = os.path.dirname(raveberry.__file__)
    configfile_path = os.path.join(raveberry_directory, "config/raveberry.ini")
except ModuleNotFoundError:
    # also allow this script to work without installed module in the git folder
    raveberry_directory = "."
    configfile_path = os.path.join(raveberry_directory, "config/raveberry.ini")
os.chdir(raveberry_directory)


def main():
    if len(sys.argv) != 2:
        usage()
        sys.exit(1)
    command = sys.argv[1]
    if command == "help":
        usage()
    elif command == "run":
        run_server()
    elif command == "system-install":
        system_install()
    elif command.lstrip("-") == "version":
        version()
    else:
        usage()
        sys.exit(1)


def usage():
    print(
        f"""usage: {sys.argv[0]} [run | system-install | system-upgrade | help | version]

run                     run a basic version of raveberry
system-install          install raveberry into the system
version                 print the version of this module
help                    show this help and exit

For more info visit https://github.com/raveberry/raveberry"""
    )


def version():
    try:
        print(pkg_resources.require("raveberry")[0].version)
    except pkg_resources.DistributionNotFound:
        print("raveberry is not currently installed")
        sys.exit(1)


def run_server():
    if not os.path.isfile("db.sqlite3"):
        print("first time running raveberry, preparing...")
        user_install()
    print("This is the basic raveberry version using a debug server.")
    print("To install with all features run `raveberry system-install`")
    try:
        subprocess.check_call(f"pgrep mopidy".split(), stdout=subprocess.DEVNULL)
    except subprocess.CalledProcessError:
        print("mopidy not yet running, starting...")
        subprocess.Popen(["mopidy"], stderr=subprocess.DEVNULL)
    subprocess.call(["scripts/runserver.sh"])


def read_config():
    config = configparser.ConfigParser()
    config.read(configfile_path)
    for section_name, section in config.items():
        for key, value in section.items():
            try:
                enabled = config.getboolean(section_name, key)
            except ValueError:
                enabled = True
            if enabled:
                os.environ[key.upper()] = value


def user_install():
    apt_packages = ["python3-pip", "ffmpeg", "atomicparsley", "mopidy", "redis-server"]
    missing_packages = []

    if shutil.which("dpkg"):
        for package in apt_packages:
            try:
                subprocess.check_call(
                    f"dpkg -s {package}".split(),
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                )
            except subprocess.CalledProcessError:
                missing_packages.append(package)
        if missing_packages:
            print(
                "please install missing packages: sudo apt-get install -y "
                + " ".join(missing_packages)
            )
            sys.exit(1)
    else:
        print(
            "Warning: dpkg is not installed, could not check if dependencies are installed! Use at your own risk!"
        )

    read_config()
    subprocess.call(["/bin/bash", "setup/user_install.sh"])


def system_install():
    print(
        """You are about to install raveberry system-wide. This will make it start on boot and enable features specified in the config file.
Depending on your configuration, this will alter some system files. (Although everything *should* work fine, backups are recommended)
Config-file location: """
        + configfile_path
    )

    answer = input(
        "Is this the configuration you want to install raveberry with? [Y/n] "
    )
    while answer not in ["", "Y", "y", "Yes", "yes", "N", "n", "No", "no"]:
        answer = input('Please answers "yes" or "no": ')
    if answer in ["N", "n", "No", "no"]:
        sys.exit(0)

    read_config()

    db_exists = not subprocess.call(
        'sudo -u postgres psql -lqt | cut -d \\| -f 1 | grep -qw "raveberry"',
        shell=True,
        stderr=subprocess.DEVNULL,
    )
    if os.environ["DB_BACKUP"] or db_exists:
        # another database is already present, do not ask for a new admin password
        pass
    else:
        while True:
            admin_password = getpass.getpass("Set admin password: ")
            admin_password_confirmed = getpass.getpass("Confirm admin password: ")
            if admin_password == admin_password_confirmed:
                os.environ["ADMIN_PASSWORD"] = admin_password
                break
            print("Passwords didn't match")
    subprocess.call(["sudo", "-E", "/bin/bash", "setup/setup.sh"])


if __name__ == "__main__":
    main()
