import logging
import subprocess
import re
import os
import configparser
import selectors

logger = logging.getLogger ('boottools')

def run (args):
    stdout = stderr = ''
    logger.debug ('run 10 args "{}"'.format (' '.join(args)))
    sel = selectors.DefaultSelector()
    p = subprocess.Popen (args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    sel.register (p.stdout.fileno(), selectors.EVENT_READ)
    sel.register (p.stderr.fileno(), selectors.EVENT_READ)
    while True:
        events = sel.select()
        for key, _ in events:
            if key.fileobj == p.stdout.fileno():
                line = p.stdout.readline()
                if not line: break
                stdout += line
                logger.debug (line.rstrip())
            elif key.fileobj == p.stderr.fileno():
                line = p.stderr.readline()
                if not line: break
                stderr += line
                logger.warn (line.rstrip())
        if p.poll() != None:
            break
    sel.close()
    stdout = stdout.strip()
    stderr = stderr.strip()

    logger.debug (f'p.returncode {p.returncode}')
    if p.returncode:
        logger.error ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode))

        #logger.error ('stdout follows:')
        #if stdout:
        #    for i in stdout.split('\n'): logger.error ('  ' + i)

        logger.error ('stderr follows:')
        if stderr:
            for i in stderr.split('\n'): logger.error ('  ' + i)

        raise Exception ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode))
    return stdout, stderr

def grep (regex, file):
    with open (file, 'r') as f:
        for l in f:
            if (re.findall (regex, l)): return 1
        return 0

def is_mounted (mntpt):
    return grep (mntpt, '/proc/mounts')

def mount (dev, mntpt, opts=[]):
    if not is_mounted (mntpt):
        run (['mount', dev, mntpt] + opts)

def umount (mntpt):
    if (is_mounted (mntpt)):
        run (['umount', mntpt])

def read_config (fn):
    if not os.path.exists (fn):
        print (f'configuration file "{fn}" not found')
        return
    config = configparser.ConfigParser (comment_prefixes='#', inline_comment_prefixes='#')
    config.read (fn)
    return config

def write_md5 (fn):
    md5, _ = run (['md5sum', fn])
    md5, rest = md5.split (' ', 1)
    with open (f'{fn}.sum', 'w') as fd:
        fd.write (md5 + '\n')
