"""
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()
