#!/bin/python3

# external modules

from os import cpu_count, path, walk
from pathlib import Path
from sys import argv, exit as s_exit
from time import sleep
from subprocess import check_output, Popen


# utility functions

def scan_source():
    _artist_dirs, _album_dirs, _full_paths = [], [], []
    for _root, _directories, _files in walk(path.expanduser(source)):
        for _dir in sorted(_directories):
            if not _root.endswith(path.expanduser(source)):
                _artist_dirs.append(_root)
    _artist_dirs = list(set(_artist_dirs))
    for _artist in sorted(_artist_dirs):
        for _root, _directories, _files in walk(path.expanduser(_artist)):
            if not _root.endswith(path.expanduser(_artist)):
                _album_dirs.append(_root)
    _album_dirs = list(set(_album_dirs))
    for _album in sorted(_album_dirs):
        for _root, _directories, _files in walk(path.expanduser(_album)):
            for _filename in _files:
                if _filename.endswith('.flac'):
                    _full_paths.append(f"{_album}/{_filename[:-5]}")
    return _album_dirs, _full_paths


def create_destination():
    for _dir in source_directories[0]:
        Path(path.expanduser(_dir.replace(path.expanduser(source), path.expanduser(destination))))\
            .mkdir(0o700, parents=True, exist_ok=True)


def scan_destination_convert_mp3():
    _i, _total_files = 0, len(source_directories)
    for _file in source_directories[1]:
        if not Path(f"{_file.replace(path.expanduser(source), path.expanduser(destination))}.mp3").is_file():
            _file_s = _file.replace(' ', '\\ ').replace("'", "\\'").replace(')', '\\)').replace('(', '\\(').replace\
                          ('&', '\\&').replace('`', '\\`').replace('$', '\\$') + '.flac'
            _file_d = _file.replace(path.expanduser(source), path.expanduser(destination)).replace(' ', '\\ ')\
                          .replace("'", "\\'").replace(')', '\\)').replace('(', '\\(').replace('&', '\\&')\
                          .replace('`', '\\`').replace('$', '\\$') + '.mp3'
            _active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
            if _active_processes >= cpu_count():
                while _active_processes >= cpu_count():
                    print(f"\nThere are already {cpu_count()} processes running...\n")
                    sleep(1)
                    _active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
            _i += 1
            _progress = _i / _total_files
            print(f"\n{_progress}% | \u001b[38;5;0;48;5;15mConverting {_file_s} to {_file_d}...\u001b[0m\n")
            if '-s' in arguments:
                _cmd = f"screen -DmS flac2pod{_i} ffmpeg -i {_file_s} -map 0:a -ab 320k -map_metadata 0" \
                       f" -id3v2_version 3 {_file_d} </dev/null; rg2sc -f -s {_file_d}"
            else:
                _cmd = f"screen -DmS flac2pod{_i} ffmpeg -i {_file_s} -c:v copy -ab 320k -map_metadata 0" \
                       f" -id3v2_version 3 {_file_d} </dev/null; rg2sc -f {_file_d}"
            Popen(_cmd, shell=True)
    _active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
    while _active_processes != 0:
        print('\nPlease wait for the remaining conversions to complete...\n')
        sleep(1)
        _active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
    sleep(1)
    print('\niPod conversion complete!\n')
    s_exit()


# retrieve typed argument
arguments = argv

source = input('Source parent directory: ')
if source.endswith('/'):
    source = source[:-1]
destination = input('Destination parent directory: ')
if destination.endswith('/'):
    destination = destination[:-1]

source_directories = scan_source()
create_destination()
scan_destination_convert_mp3()
