import logging
import os
import shutil
import subprocess
from multiprocessing import Process
from random import shuffle
from signal import SIGKILL

from school_ringer_modules.calendar_editor import is_holiday_today
from school_ringer_modules.config import sound_path, debug, config_path
from school_ringer_modules.system import run_command


def default_sound() -> str:
    """
    Возвращает звук стандартного звонка. По умолчанию это ring01.mp3.
    :return: строка с именем файла
    """
    try:
        sound_files = os.listdir(f'{sound_path}')
    except Exception:
        if not run_command(f'file {config_path}').strip().endswith(': directory'):
            run_command(f'pkexec mkdir -p {sound_path}')
        sound_files = []
    if 'ring01.mp3' not in sound_files and debug is True:
        shutil.copyfile('ring01.mp3', f'{sound_path}/ring01.mp3')
        logging.info('ring01.mp3 не был найден в папке со звуками и скопирован из приложения')
    logging.info('Звук ring01.mp3 установлен как звук по умолчанию')
    return 'ring01.mp3'


def ring_the_call(filename: str, play_music=False) -> None:
    """
    Функция вызывает воспроизведение звонка
    :param filename: имя файла для воспроизведения
    @param play_music: является ли звонок звонком с урока
    """
    if not is_holiday_today():
        try:
            subprocess.run('pkill play', shell=True)
            logging.info(f'pkilled play')
            subprocess.run('pkill cat', shell=True)
            logging.info(f'pkilled cat')
            run_command('export $(dbus-launch)')
            try:
                with open(f'{config_path}/pid', 'r') as inp:
                    playing_pid = int(inp.readline())
                os.kill(playing_pid, SIGKILL)
            except Exception as e:
                logging.info(f'Не удалось остановить процесс воспроизведения: {e}')
            player = Process()
            sound_to_play = f'{sound_path}/{filename}'
            command_to_play = f'sudo -u school-ringer play {sound_to_play}'
            if play_music and run_command(f'py-ini-config get {config_path}/school-ringer.conf Main '
                                          f'is_breaks_music_on').strip().lower() == 'true':
                music_playlist = get_music_for_breaks()
                logging.info(f'После этого звонка с урока будет играть музыка: {music_playlist}')
                pause = 0
                pause_from_config = run_command(
                    f'py-ini-config get {config_path}/school-ringer.conf Main music_pause').strip()
                if pause_from_config:
                    pause = int(pause_from_config)
                command_to_play += f' && sleep {pause}'
                for song in music_playlist:
                    if '.' not in song:
                        logging.info('У файла отсутствует расширение.')
                        continue
                    if '$' in song or '`' in song:
                        logging.info(f'В имени файла {song} присутствуют недопустимые символы')
                        continue
                    song_codec = song.strip('"').split('.')[-1].strip()
                    volume = int(run_command(
                        f'py-ini-config get {config_path}/school-ringer.conf Main music_volume')) / 100
                    command_to_play += f' && cat {song} | sudo -u school-ringer play -v {volume} -t {song_codec} -'
            try:
                player.terminate()
            except Exception as e:
                logging.info(f'Звук не воспроизводился. Исключение {e}')
            player = Process(target=lambda: run_command(command_to_play), args=())
            player.start()
            print(player.pid, file=open(f'{config_path}/pid', 'w'))
            logging.info(f'Звонок воспроизведён')
            return
        except Exception as e:
            print(f'При попытке воспроизведения возникла ошибка: {e}')
            logging.info(f'При попытке воспроизведения возникла ошибка: {e}')
    else:
        logging.info('Каникулы. Звонок не воспроизведён.')


def get_music_for_breaks() -> [str]:
    """
    Возращает список имён файлов для воспроизведения на перемене путём выбора из указанной папки
    всех файлов mp3, wav и ogg
    @return: список строк с именами файлов для воспроизведения
    """
    ans = []
    music_path = run_command(f'py-ini-config get {config_path}/school-ringer.conf Main music_folder').strip()
    if music_path:
        music_path = music_path.lstrip('"').rstrip('"')
        for file in os.listdir(music_path):
            if file.split('.')[-1] in ('mp3', 'wav', 'ogg'):
                ans.append(f'"{music_path}/{file}"')
        if (run_command(f'py-ini-config get {config_path}/school-ringer.conf Main music_shuffle').strip().lower() ==
                'true'):
            shuffle(ans)
        logging.info('Список музыки для перемен: ')
        logging.info(ans)

    else:
        logging.info('В файле конфигурации нет информации о папке с музыкой.')
    return ans
