"""
Autochanger onlineClamping sequence
===================================

"""
import sys
import time
from org.lsst.ccs.scripting import CCS
from java.time import Duration
from java.lang import Exception


class Autochanger(object):
    def __init__(self, subsystem_name, n_sequences):
        self.name = subsystem_name
        self.n_seq = n_sequences

        self.onlineClamps = CCS.attachSubsystem(self.name + "/onlineClamps")

    def wait_for_user(self, text):
        print("Next command: %s\n" % text)
        print("Press any key to proceed...")
        return raw_input()

    def initialise_clamp_position(self):
        print("Initialisation..")

        if self.onlineClamps.sendSynchCommand("isLocked"):
            self.unlock()

        if self.onlineClamps.sendSynchCommand("isHomingDone"):
            self.open()
        else:
            self.open_and_homing()

    def open_and_homing(self):
        # self.wait_for_user("onlineClamps: openAndHoming")
        print("homing...")
        self.onlineClamps.sendSynchCommand("homing")
        
    def open(self):
        # self.wait_for_user("onlineClamps: open")
        print("openClamps...")
        self.onlineClamps.sendSynchCommand("openClamps")

    def close(self):
        # self.wait_for_user("onlineClamps: close")
        print("closeClamps...")
        self.onlineClamps.sendSynchCommand("closeClamps")

    def lock(self):
        # self.wait_for_user("onlineClamps: lock")
        print("lockClamps...")
        self.onlineClamps.sendSynchCommand("lockClamps")

    def unlock(self):
        # self.wait_for_user("onlineClamps: unlock")
        print("unlockClamps...")
        self.onlineClamps.sendSynchCommand("unlockClamps")

    def clamp_test_sequence(self):
        self.close()
        self.lock()
        self.unlock()
        self.open()

    def timed_clamp_test_sequence(self):
        t0 = time.time()
        self.close()
        t1 = time.time()
        self.lock()
        t2 = time.time()
        self.unlock()
        t3 = time.time()
        self.open()
        t4 = time.time()

        dcloselock = t2 - t0
        dunlockopen = t4 - t2

        print("\n")
        print("Duration of actions:\n")
        print("\tclose: %.3fs" % (t1 - t0))
        print("\tlock: %.3fs" % (t2 - t1))
        print("\tunlock: %.3fs" % (t3 - t2))
        print("\topen: %.3fs" % (t4 - t3))
        print("\t---")
        print("\tclose + lock: %.3fs" % (dcloselock))
        print("\tunlock + open : %.3fs" % (dunlockopen))
        print("\ttotal sequence: %.3fs" % (t4 - t0))
        print("\n")

        return (dcloselock, dunlockopen)

    def run_sequence(self):
        print(__doc__)

        self.initialise_clamp_position()    

        duration_closelock = 0
        duration_unlockopen = 0

        for i in range(self.n_seq):
            print("Sequence %d/%d" % (i+1, self.n_seq))
            # self.clamp_test_sequence()
            dcl, duo = self.timed_clamp_test_sequence()
            duration_closelock += dcl
            duration_unlockopen += duo

        if self.n_seq != 0:
            duration_closelock *= 1000 
            duration_closelock /= self.n_seq
            duration_unlockopen *= 1000
            duration_unlockopen /= self.n_seq
        
        print("\n\n")
        print("FINAL RESULTS")
        print("-------------")
        print("%d sequences run" % self.n_seq)
        print("average duration for close / lock = %d ms" % duration_closelock)
        print("average duration for unlock / open = %d ms" % duration_unlockopen)
        print("\n\n")


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-s", "--subsystem", 
        type=str, default="fcs", 
        choices=["fcs", "autochanger-standalone_AC1", "autochanger-standalone_AC2"],
        help="Name of the running subsystem: 'fcs' or 'autochanger-standalone_AC1/2'")
    parser.add_argument(
        "-n", "--n_sequences", 
        type=int, default=1,
        help="Number of cycles to go through.")
    args = parser.parse_args()

    Autochanger(args.subsystem, args.n_sequences).run_sequence()
