#!/usr/bin/env python

#A driver for the Chemspeed FLEX robot
#Utilises file exchange to communicate with the Chemspeed FLEX
#Made by Hatem Fakhruldeen 23/03/2022

import time
import os
import subprocess
        
class ChemSpeedFlexDriver:
    
    def __init__(self, app_path: str):
        self._process = None
        self._exchange_dir = r'C:\fileExchange'
        self._app_path = app_path #r'C:\Users\Operator\Desktop\door_operation_alt.bat'
        self._initialsed = False
        self._door_open = False
        self._job_started = False
        # clear the files inside the exchange folder
        self._clear_exchange_dir()

    def initialse(self):
        # start the application
        self._process = subprocess.Popen(self._app_path)
        init_path = os.path.join(self._exchange_dir, 'init.txt')
        while not os.path.exists(init_path):
            time.sleep(0.5)
        self._initialsed  = True
        print(f'Chemspeed application {self._app_path} is started. Ready to receive commands')

    def open_door(self):
        if (self._initialsed):
            if (not self._door_open):
                open_file_path = os.path.join(self._exchange_dir,'open.txt')
                self._create_file(open_file_path)
                while os.path.exists(open_file_path):
                        time.sleep(0.5)
                self._door_open = True
            else:
                print('door is already open. Ignoring the current command')
        else:
            print('Please start the chemspeed application by calling run() method.')

    def close_door(self):
        if (self._initialsed):
            if (self._door_open):
                close_file_path = os.path.join(self._exchange_dir,'close.txt')
                self._create_file(close_file_path)
                while os.path.exists(close_file_path):
                        time.sleep(0.5)
                self._door_open = False
            else:
                print('door is already closed. Ignoring the current command')
        else:
            print('Please start the chemspeed application by calling run() method.')

    def start_job(self):
        if (self._initialsed):
            if (not self._door_open):
                if (not self._job_started):
                    job_start_path = os.path.join(self._exchange_dir,'start_job.txt')
                    self._create_file(job_start_path)
                    while os.path.exists(job_start_path):
                        time.sleep(0.5)
                    self._job_started = True
                    print('Job started')
                        
                else:
                    print('A job is already started. Cannot start a new job')
            else:
                print('Cannot run the job since chemspeed door is open. Please the doors.')
        else:
            print('Please start the chemspeed application by calling run() method.')
        return self._job_started
    
    def is_job_complete(self):
        if (self._initialsed):
            job_complete_path = os.path.join(self._exchange_dir,'job_complete.txt')
            return os.path.exists(job_complete_path)
        else:
            print('Please start the chemspeed application by calling run() method.')

    def terminate(self):
        if (self._initialsed):
            job_complete_path = os.path.join(self._exchange_dir,'job_complete.txt')
            if self._job_started and not os.path.exists(job_complete_path):
                print('Cannot terminate application since job is still running. Try again when the job is complete.')
            else :
                terminate_path = os.path.join(self._exchange_dir,'terminate.txt')
                self._create_file(terminate_path)
                self._process.wait()
                self._clear_exchange_dir()
                print('Chemspeed application is terminated and its exchange directory cleaned.')
        else:
            print('Please start the chemspeed application by calling run() method.')

    def _create_file(self, file_name):
        with open(os.path.join(self._exchange_dir, file_name), 'w') as f:
            pass

    def _clear_exchange_dir(self):
        for f in os.listdir(self._exchange_dir):
            if f.endswith('.txt'):
                os.remove(os.path.join(self._exchange_dir,f))

