"""
To run this script while being connected to a server for saving data, we need 
to setup the two interfaces eth0 and usb0. To route the ssh connection via usb0 
we can apply a reduced iptables approach by setting the route for this specific
ip to usb0: sudo route add -host 192.168.137.2 dev usb0
"""


import subprocess
import argparse
import time
import sys
from sensorpi import __main__ as sp

def arg_parser():
    """
    Parse the command line arguments.

    Returns
    -------
    Namespace
        The namespace containing the parsed arguments.

    """
    parser = argparse.ArgumentParser(
        description="Set up the black box lighting and run measurements from \
            different sensors and send data to an influxdb database. More specific \
                information can be found in the rpi-rgb-led-matrix and \
                    sensorpi documentations.")
    parser.add_argument("-C", "--screen_chain", action="store", default="1", 
                        type=str, help="Daisy-chained boards. Default: 1.")
    parser.add_argument("-P", "--screen_parallel", action="store", default="1", 
                        type=str, help="For Plus-models or RPi2: parallel \
                            chains. 1..3. Default: 1")
    parser.add_argument("--lighting", action="store", default="0", type=str,
                        help="Set the lighting and interval for each Display. \
                            For special light pulses set two options for one \
                                display in the desired order. Format: \
                                    DisplayNo:R,G,B:LD,cycle_\
                                        DisplayNo:R,G,B:LD,cycle;...")
    parser.add_argument("--logging", type=int, default = 0,
                        help="Activate sensorpi for logging data. default = 0")
    parser.add_argument("--config", "-c", type=argparse.FileType("r"),
                        help="config.edn file to use.")
    parser.add_argument("--measurement", "-m", type=str,
                        help="Measurement name.")
    parser.add_argument("--newconfig", "-n", type=str,
                        help="Creates a new config at the given path.")
    parser.add_argument("--interval", "-i", type=int,
                        help="Interval between measurements in seconds.")
    parser.add_argument("--verbose", "-v", action="count", default=0)
    return parser.parse_args()


def sub_proc():
    """
    Opens a subprocess pipe via ssh to the remote machine.
    
    The identity file needs to be specified here (similarly to the 
    sshd_config), login options in sshd_config and ssh_config need to be 
    adjusted to avoid the PermissionDenied (Publickey, etc.) error.
    To use rsa, other keys might need to be disabled/erased.

    Returns
    -------
    Subprocess pipe.

    """
    #
    return(subprocess.Popen([
                                "ssh", "-i", "/home/PATH/.ssh/id_rsa", 
                                "pi@192.168.137.2"
                                ],
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            encoding='utf8'))

def main():
    """
    Runs a logging and lighting script on two Raspberry Pis communicating via
    ssh. The remote machine handles illumination with LED matrix displays. The 
    main machine runs a logging script, communicates start up and shut down 
    to remote, and parses the initial arguments.

    Returns
    -------
    None.

    """
    sys.path.append('/home/PATH/sensorpi/')
    try:
        args = arg_parser()
        path = "cd rpi-rgb-led-matrix/bindings/python/samples \n"
        if args.lighting != 0:
            command="sudo python3 manual_color_fill.py --lighting \
                "+args.lighting+" --led-chain "+args.screen_chain+" \
                    --led-parallel "+args.screen_parallel+" \n"
            subp=sub_proc()
            subp.stdin.write(path)
            subp.stdin.flush()
            subp.stdin.write(command)
            subp.stdin.flush()
            print("Illumination starts in 1 min...")
        else:
            print("Light conditions not defined. Skipping setup.")
        if args.logging != 0:
                if args.newconfig is not None:
                    sp.create_config(args.newconfig)
                    sp.log.info(f"Config created at {args.newconfig}."
                     f"Edit it and restart the program with it!")
                    exit()
                if args.measurement is None:
                    args.measurement = input("Name of the measurement: ")
                if args.interval is None:
                    args.interval = int(input(
                        "Wait seconds between measurements: "))
                if args.config is None:
                    config = sp.read_config(sp.find_config())
                else:
                    args.config.close()
                    config = sp.read_config(args.config.name)
                sp.main(args.interval, args.measurement, config, args.verbose)
                print("Data can be checked in grafana (localhost:3000). \
                      (Storage default: localhost:8086)")
        else:
            print("No logging defined. Skipping setup.")
            time.sleep(5)
        
        print("Setup completed. Press CTRL-C to stop.")
        
        while True:
            time.sleep(5)
       
    except KeyboardInterrupt:
        sp.log.warning("\nProgram is exiting...")
        
    finally:
        print("...wrapping up...")
        subp.stdin.write('C')
        subp.stdin.flush()
        time.sleep(5)
        print("...done!")
        sys.exit()


if __name__ == "__main__":
    main()