#!/usr/bin/env python3
# -*- coding: utf-8 -*-

'''
Sequencer module for Observation Blocks (OBs) in JSON format
'''

# System modules
import importlib
import json
import sys
from astropy.time import Time

# Custom modules
from utils.logger import log
# import templates


class Sequencer():
    '''
    Manage a sequence of JSON Observation Blocks (OBs)
    '''

    def __init__(self):
        '''Constructor'''
        self.ob = []
        self.error = []

    def load_file(self, ob_file):
        '''Load a JSON file with an OB'''

        with open(ob_file, encoding="utf-8") as jsonfile:
            log.info(f"Loading the ob from file {ob_file}")

            try:
                self.error = []
                self.ob = json.load(jsonfile)
            except json.decoder.JSONDecodeError as e:
                msg = "SEQUENCER: Probably malformed json"
                log.error(msg)
                log.error(e)
                self.error.append(msg)
                self.error.append(e)
            except UnicodeDecodeError as e:
                msg = "SEQUENCER:Not a text file"
                log.error(msg)
                log.error(e)
                self.error.append(msg)
                self.error.append(e)
            except Exception as e:
                msg = "SEQUENCER: Not handled exception"
                log.error(msg)
                log.error(e)
                self.error.append(msg)
                self.error.append(e)
                raise SystemExit(e) from e

    def execute(self):
        '''Execute the template(s) contained in the loaded OB'''
        ob = self.ob if isinstance(self.ob, list) else [self.ob]

        log.info(f"There are {len(ob)} templates in the ob")

        now = Time.now()

        for template in ob:
            log.info("--------------------------------------------")
            try:
                self.error = []
                # Importing the module given its name in the json.
                tplmodule = importlib.import_module(
                    "templates." + template["template"])
                # tplmodule = getattr(templates, template["template"])
                # Every template module has a Template() class.
                tpl = tplmodule.Template()
                # Run the template given its parameters in the json.
                tpl.run(template["params"])

            except AttributeError as e:
                msg = "SEQUENCER: Attribute Error"
                log.error(msg)
                log.error(e)
                self.error.append(msg)
                self.error.append(e)

            except KeyError as e:
                msg = f"{e} is not defined"
                log.error(msg)
                self.error.append(msg)

            except KeyboardInterrupt as e:
                msg = "Interrupt triggered"
                log.error(msg)
                log.error(e)
                self.error.append(msg)
                self.error.append(e)
                tpl.abort()
                self.abort()
                return

        log.debug(f"Total elapsed time: {(Time.now()-now).sec :.2f}s")

    def abort(self):
        '''Abort the execution of the OB'''
        log.error("Aborting sequencer")
        sys.exit(1)


if __name__ == "__main__":

    seq = Sequencer()
    seq.load_file(sys.argv[1])
    seq.execute()
