'''
  __  __           _            
 |  \/  | __ _ ___| |_ ___ _ __ 
 | |\/| |/ _` / __| __/ _ \ '__|
 | |  | | (_| \__ \ ||  __/ |   
 |_|  |_|\__,_|___/\__\___|_|   
                                
Master Python script that will trigger other scripts at every chosen time pace
This script is triggered as a systemd service used as an alternative to cronjobs

Attention: 
    to do -> prevent SARA R4 Script to run again if it's taking more than 60 secs to finish (using a lock file ??) 

First time: need to create the service file

-->sudo nano /etc/systemd/system/master_nebuleair.service

⬇️
[Unit]
Description=Master manager for the Python loop scripts
After=network.target

[Service]
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/master.py
Restart=always
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/master.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/master_errors.log

[Install]
WantedBy=multi-user.target
⬆️

Reload systemd (first time after creating the service):
    sudo systemctl daemon-reload

Enable (once), start (once and after stopping) and restart (after modification)systemd:
    sudo systemctl enable master_nebuleair.service
    sudo systemctl start master_nebuleair.service
    sudo systemctl restart master_nebuleair.service

Check the service status:
    sudo systemctl status master_nebuleair.service


Specific scripts can be disabled with config.json
    Exemple: stop gathering data from NPM
    Exemple: stop sending data with SARA R4

'''
import time
import threading
import subprocess
import json
import os

# Base directory where scripts are stored
SCRIPT_DIR = "/var/www/nebuleair_pro_4g/"
CONFIG_FILE = "/var/www/nebuleair_pro_4g/config.json"

def load_config():
    """Load the configuration file to determine which scripts to run."""
    with open(CONFIG_FILE, "r") as f:
        return json.load(f)

def run_script(script_name, interval, delay=0):
    """Run a script in a synchronized loop with an optional start delay."""
    script_path = os.path.join(SCRIPT_DIR, script_name)  # Build full path
    next_run = time.monotonic() + delay  # Apply the initial delay

    while True:
        config = load_config()
        if config.get(script_name, True):  # Default to True if not found
            subprocess.run(["python3", script_path])
        
        # Wait until the next exact interval
        next_run += interval
        sleep_time = max(0, next_run - time.monotonic())  # Prevent negative sleep times
        time.sleep(sleep_time)

# Define scripts and their execution intervals (seconds)
SCRIPTS = [
    ("RTC/save_to_db.py", 1, 0),                # SAVE RTC time every 1 second, no delay
    ("NPM/get_data_modbus_v3.py", 10, 0),       # Get NPM data (modbus 5 channels) every 10s, with 2s delay
    ("envea/read_value_v2.py", 10, 0),          # Get NPM data (modbus 5 channels) every 10s, with 2s delay
    ("loop/SARA_send_data_v2.py", 60, 1),       # Send data every 60 seconds, with 2s delay
    ("BME280/get_data_v2.py", 120, 0),          # Get BME280 data every 120 seconds, no delay
    ("sqlite/flush_old_data.py", 86400, 0)        # flush old data inside db every day ()
]

# Start threads for enabled scripts
for script_name, interval, delay in SCRIPTS:
    thread = threading.Thread(target=run_script, args=(script_name, interval, delay), daemon=True)
    thread.start()

# Keep the main script running
while True:
    time.sleep(1)

