"""
FCS single filter sequence
==========================
Test a sequence of setFilter commands with a single filter in the camera.
The order of the sockets is picked up randomly.

"""
from org.lsst.ccs.scripting import CCS
from org.lsst.ccs.command import *
from java.time import Duration
from java.lang import Exception
from time import sleep, time
from random import choice

CCS.setThrowExceptions(True)


class SingleFilterSequence(object):
    name = "fcs"

    def __init__(self, filter_id, n_sequences):
        self.id = filter_id
        self.n_seq = n_sequences

        self.fcs = CCS.attachSubsystem(self.name)
        self.autochanger = CCS.attachSubsystem("%s/%s" % (self.name, "autochanger"))
        self.carousel = CCS.attachSubsystem("%s/%s" % (self.name, "carousel"))
        print("Connected to %s" % self.name)

        self.timeout = Duration.ofMinutes(3)

    def pick_next_socket(self):
        socket_list = range(1, 6)
        next_socket = choice(socket_list)
        previous_socket = int(self.carousel.sendSynchCommand("getSocketAtStandbyID"))
        while next_socket == previous_socket:
            next_socket = choice(socket_list)
        
        return next_socket

    def set_filter(self):
        t0 = time()

        self.fcs.sendSynchCommand(self.timeout, "setFilter", self.id)

        elapsed_time = time() - t0

        print("+ set filter [%dmin%ds]" % (elapsed_time // 60, elapsed_time % 60))

    def set_no_filter(self):
        t0 = time()

        self.fcs.sendSynchCommand(self.timeout, "setNoFilter")

        elapsed_time = time() - t0

        print("+ set no filter [%dmin%ds]" % (elapsed_time // 60, elapsed_time % 60))

    def rotate_to_socket(self, socket_id):
        t0 = time()

        self.carousel.sendSynchCommand("rotateSocketToStandby", "socket%d" % socket_id)

        elapsed_time = time() - t0

        print("+ rotate to socket [%dmin%ds]" % (elapsed_time // 60, elapsed_time % 60))


    def run(self):
        """Execute the sequence"""
        print(__doc__)
        socket_id = 0
        # Make sure there the autochanger is empty first
        if self.autochanger.sendSynchCommand("isHoldingFilter"):
            self.fcs.sendSynchCommand("storeFilterOnCarousel")
        # Make sure the autochanger trucks are aligned
        self.autochanger.sendSynchCommand("alignFollower")

        for i in range(self.n_seq):
            print("Starting sequence %d/%d" % (i + 1, self.n_seq))
            t0 = time()
        
            self.set_filter()
            socket_id = self.pick_next_socket()
            self.rotate_to_socket(socket_id)
            self.set_no_filter()

            elapsed_time = time() - t0
            
            print("=> sequence took %dmin%ds\n" % (elapsed_time // 60, elapsed_time % 60))

            # one min pause for motor cooldown
            sleep(60)

        print("Done")
    

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-i", "--filter_id",
        type=int, required=True,
        help="Filter ID to be set")
    parser.add_argument(
        "-n", "--n_sequences", 
        type=int, default=1, 
        help="Number of full sequences executed (default 1)")

    args = parser.parse_args()

    SingleFilterSequence(args.filter_id, args.n_sequences).run()
