import logging
import os
import sys
import tempfile
from argparse import ArgumentParser
from pathlib import Path

import daemon
import psutil

from i3configger import __version__
from i3configger.lib import I3Configger, IniConfig, IpcControl

log = logging.getLogger()


def configure_logging(verbose, logfile=None, daemon=False):
    level = logging.DEBUG if verbose else logging.INFO
    fmt = '%(asctime)s %(name)s %(levelname)s: %(message)s'
    if daemon:
        if not logfile:
            logfile = Path(tempfile.gettempdir()) / 'i3configger.log'
        logging.basicConfig(filename=logfile, format=fmt, level=level)
        return
    logging.basicConfig(stream=sys.stdout, format=fmt, level=level)
    if not logfile:
        return
    fileHandler = logging.FileHandler(Path(logfile).expanduser())
    fileHandler.setFormatter(logging.Formatter(fmt))
    fileHandler.setLevel(level)
    log.addHandler(fileHandler)
    log.debug("logging to %s", logfile)


def parse_args():
    p = ArgumentParser('i3configger')
    p.add_argument('--ini-path', action="store",
                   help="path to i3configger.ini", default=None)
    p.add_argument('--verbose', action="store_true", default=False)
    p.add_argument('--reload', action="store_true", default=False,
                   help="reload i3 instead of restart (not i3bar update)")
    p.add_argument('--version', action='version', version=__version__)
    p.add_argument('--daemon', action="store_true",
                   help="watch and build as daemon", default=False)
    p.add_argument('--watch', action="store_true",
                   help="watch and build in foreground", default=False)
    p.add_argument('--kill', action="store_true",
                   help="kill the deamon if it is running", default=False)
    return p.parse_args()


def get_foreign_processes():
    procs = [p for p in psutil.process_iter() if p.name() == 'i3configger']
    return [p for p in procs if p.pid != os.getpid()]


def daemonize(buildDefs, maxerrors, verbose, logfile=None):
    foreignProcesses = get_foreign_processes()
    if foreignProcesses:
        sys.exit("i3configger already running (%s)" % foreignProcesses)
    context = daemon.DaemonContext(
        working_directory=Path(__file__).parent,
        # TODO check if this umask is ok
        umask=0o002)
    # todo handle signals properly
    # context.signal_map = {
    #     signal.SIGTERM: program_cleanup,
    #     signal.SIGHUP: 'terminate',
    #     signal.SIGUSR1: reload_program_config}
    if verbose:
        # spew output to terminal from where daemon was started
        context.stdout = sys.stdout
        context.stderr = sys.stderr
    with context:
        configure_logging(verbose, logfile, daemon=True)
        i3configger = I3Configger(buildDefs, maxerrors)
        i3configger.watch_guarded()


def main():
    args = parse_args()
    cnf = IniConfig(IniConfig.get_config(args.ini_path))
    log.debug("config: %s", cnf)
    if args.kill:
        # todo some error handling
        for process in get_foreign_processes():
            print("killing %s" % process.pid)
            process.kill()
        return 0
    if args.reload:
        IpcControl.refresh = IpcControl.reload_i3
    if args.daemon:
        daemonize(cnf.buildDefs, cnf.maxerrors, args.verbose, cnf.logfile)
    configure_logging(args.verbose, cnf.logfile)
    i3Configger = I3Configger(cnf.buildDefs, cnf.maxerrors)
    if args.watch:
        try:
            i3Configger.watch()
        except KeyboardInterrupt:
            sys.exit("bye")
    else:
        i3Configger.build()
        # todo is there a way to reload the status bar without restarting i3?
        IpcControl.refresh()


if __name__ == '__main__':
    # for dev
    sys.argv = ['dev', '--verbose', '--watch']
    sys.exit(main())

@@ -3314,24 +3314,38 @@
 nf.logfile)%0A
+    else:%0A    
     configur
@@ -3377,24 +3377,28 @@
 nf.logfile)%0A
+    
     i3Config
@@ -3445,24 +3445,28 @@
 errors)%0A    
+  
+  
 if args.watc
@@ -3468,16 +3468,20 @@
 .watch:%0A
+    
         
@@ -3489,32 +3489,36 @@
 ry:%0A            
+    
 i3Configger.watc
@@ -3529,16 +3529,20 @@
         
+   
+ 
 except K
@@ -3563,32 +3563,36 @@
 pt:%0A            
+    
 sys.exit(%22bye%22)%0A
@@ -3591,30 +3591,38 @@
 (%22bye%22)%0A    
+ 
+   
 else:%0A
+    
         i3Co
@@ -3649,23 +3649,23 @@
     
+    
 # todo 
-is there
+need
  a w
@@ -3676,27 +3676,26 @@
 o re
-load the status bar
+fresh i3bar config
  wit
@@ -3716,18 +3716,18 @@
 g i3
-?
 %0A
+ 
         
 IpcC
@@ -3714,32 +3714,35 @@
 ing i3%0A         
+   
 IpcControl.refre
@@ -3746,16 +3746,32 @@
 fresh()%0A
+        return 0
 %0A%0Aif __n

make structure of main function clearer