#!/usr/bin/env python3.8
import os, sys, subprocess, re, time
from datetime import datetime

import daemon
import logging

LOGGING = False


log_file_dir = os.path.abspath(sys.argv[1]) if sys.argv[1] != '-' else '-'
timeout = float(sys.argv[2] if len(sys.argv) >= 3 else 60)
computer_prefix = sys.argv[3] if len(sys.argv) >= 4 else ""
daemonlock_file = sys.argv[4] if len(sys.argv) >= 5 else ""


def is_active(app, title):
    if (app == "desktop_window.Nautilus") and (title == "Desktop"):
        return False

#    if 'is active' in subprocess.getoutput("gnome-screensaver-command -q"):
#        return False
#
#    if 'lockscreen' in subprocess.getoutput("ps ax | grep '/usr/lib/unity/unity-panel-service .*[l]ockscreen'"):
#        return False

    if daemonlock_file:
        with open(daemonlock_file, "r") as f:
            daemonlock_str = f.readline()
            log_dbg(f"Read from daemonlock_file {daemonlock_str}")

            if "Locked" in daemonlock_str:
                return False


    return True

def _get_output(cmd):
    res = subprocess.run(cmd, shell=True, capture_output=True)
    if res.returncode != 0:
        print(f"ERROR: The command {cmd} resulted in returncode={res.returncode}", file=sys.stderr, flush=True)
        print(f"res={res}", file=sys.stderr, flush=True)
        raise RuntimeError(f"Cannot exec cmd={cmd}")
    return res.stdout.decode("utf-8")

def get_active_program():
    active_window_string = _get_output("xprop -root | grep '_NET_ACTIVE_WINDOW(WINDOW)'")
    active = re.findall(r'#\s+0x(\w+)', active_window_string)[0]
    active = "0x" + "0" * (8-len(active)) + active

    program = _get_output("wmctrl -lx | grep %s" % active).splitlines()[0]
    _, _, app, _, title = program.split(None, 4)
    log_dbg(f"app={app}, title={title}")
    return app, title

#def get_timestamp():
#    #    return datetime.now(tzlocal()).strftime('%Y-%m-%d_%T%Z')
#    return commands.getoutput("date +'%Y-%m-%d_%H-%M-%S'")
def get_timestamp():
    return time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())


with daemon.DaemonContext():
    if LOGGING:
        logging.basicConfig(level=logging.DEBUG, filename="/tmp/log_linux-app-logger.txt",
                format="%(asctime)s|%(levelname)s|%(message)s",
                datefmt="%Y-%m-%d_%H:%M:%S")
        log_dbg = logging.debug
    else:
        log_dbg = lambda *args, **kwargs: None
    log_dbg("Start")

    previous_state_was_active = True
    should_print = True
    cur_date = ""
    prev_date = ""
    time_of_screensaver_start = 0
    is_first_record_after_start = True
    log_dbg("inside daemon")
    while True:
        try:
            log_dbg("\n===\nNext iter")
            prev_date = cur_date
            cur_timestamp = get_timestamp()
            cur_date = cur_timestamp.split("_")[0]
            cur_log_file = os.path.join(log_file_dir, "winlog_" + cur_date)
            app, title = get_active_program()
            if is_active(app, title):
                log_dbg("is_active=True, previous_state_was_active={previous_state_was_active}")
                log_line = '%s\t%s\t%-30s\t%s\n' % (cur_timestamp, computer_prefix, app, title)
                if not previous_state_was_active:
                    dt_sleep = time.time() - time_of_screensaver_start
                    time_of_screensaver_start = 0
                    if (dt_sleep > 60) and (cur_date == prev_date):
                        log_line_from_screensaver_work = "rest {} min on {} ??????????????????????????????".format(int(dt_sleep/60), computer_prefix)
                        log_line = log_line_from_screensaver_work + "\n\n" + log_line
                        pass

                previous_state_was_active = True
                should_print = True
            else:
                log_dbg("is_active=False, previous_state_was_active={previous_state_was_active}")
                if previous_state_was_active:
                    time_of_screensaver_start = time.time()

                    log_line = '%s\t%s\t%-30s\t%s\n' % (cur_timestamp, computer_prefix, "Screensaver", "\n\n\n")
                    should_print = True
                else:
                    log_line = ""
                    should_print = False

                previous_state_was_active = False

            if is_first_record_after_start:
                if os.path.isfile(cur_log_file):
                    log_line = "\nrest ????????\n\n(start)\n" + log_line
                else:
                    log_line = "(start)\n" + log_line
                is_first_record_after_start = False

            if should_print:
                if log_file_dir == '-':
                    print(log_line, end="")
                else:
                    with open(cur_log_file, 'a') as f:
                        f.write(log_line)
        except Exception:
            import traceback
            err_file = os.path.join(log_file_dir, "winlog_" + cur_date + ".err")
            with open(err_file, 'a') as f:
                traceback.print_exc(None, f);

        time.sleep(timeout)
