'''
>> The Farmbot must necessarily be switched on and connected.
>> The sequence to be executed must be saved in the Web App: its name must be
entered in full in the "Test input" paragraph (as a string within the
"sequence1" / "sequence2" variable).
'''

# Test input - please change with two of your own sequences
sequence1 = 'Message 1 - Simple'
sequence2 = 'Message 2 - Long'

sequnece_names = [sequence1, sequence2]

# Import
from farmbot import Farmbot
import multiprocessing
import requests

# Get Farmbot login credentials - EMAIL and PASSWORD to change with your own
def get_credentials():
    EMAIL = "email"
    PASSWORD = "password"
    SERVER = "https://my.farm.bot"

    return EMAIL, PASSWORD, SERVER

# Get headers
def get_headers():
    # Get credetials
    EMAIL, PASSWORD, _ = get_credentials()

    # FarmBot Web App token
    HEADERS = {'content-type':'application/json'}
    USER = {'user':{'email':EMAIL, 'password':PASSWORD}}
    SITE_token = 'https://my.farmbot.io/api/tokens'

    response_token = requests.post(SITE_token, headers = HEADERS, json = USER)
    TOKEN = response_token.json()['token']['encoded']

    # Headers
    HEADERS = {'Authorization':'Bearer ' + TOKEN,
               'content-type':"application/json"}

    return HEADERS

# Sequences ID - all the sequences saved in the Web App
def get_sequencesID():
    # FarmBot Web App token
    HEADERS = get_headers()
    SITE_sequences = 'https://my.farmbot.io/api/sequences'

    response_sequences = requests.get(SITE_sequences, headers = HEADERS)
    sequences = response_sequences.json()

    # Dict for sequences ID
    all_sequences = {}
    for i in range(0, len(sequences) - 1): 
        all_sequences[sequences[i]['name']] = sequences[i]['id']

    return all_sequences

# Log initialization message
def send_firstlog():
    # Headers
    HEADERS = get_headers()  
    SITE_logs = 'https://my.farmbot.io/api/logs'

    # Send log
    log = {'message':'Initialization message', 'type':'info'}
    response = requests.post(SITE_logs, headers = HEADERS, json = log)
    
    return response

# Get the last log message
def get_lastlog():
    
    def get_first(elem):
        
        return elem[0]

    # FarmBot Web App token
    HEADERS = get_headers()
    SITE_logs = 'https://my.farmbot.io/api/logs'

    response_logs = requests.get(SITE_logs, headers = HEADERS)
    logs = response_logs.json()

    # Logs list
    all_logs = []
    for log in logs:
        all_logs.append([log['updated_at'], log['message']])

    # Logs reorganization
    all_logs.sort(reverse = True, key = get_first)

    # Last log
    last_log = all_logs[0][1]

    return last_log

# Command the Farmbot a sequence
def farmbot_sequence(sequence):
    # Handler
    class MyHandler:
        
        def on_log(self, bot, log):
            print("LOG: " + log['message'])
        
        def on_connect(self, bot, mqtt_client):
            print("\nConnected.")
            print("The Farmbot will execute: " + sequence + ".\n")
            SEQUENCE_ID = sequences[sequence]
            bot._do_cs("execute", {"sequence_id":SEQUENCE_ID})
        
        def on_change(self, bot, state):
            pass
        
        def on_response(self, bot, response):
            pass
        
        def on_error(self, bot, response):
            pass
        
    # Get credentials
    EMAIL, PASSWORD, SERVER = get_credentials()

    fb = Farmbot.login(email = EMAIL, password = PASSWORD, server = SERVER)
    handler = MyHandler()
    fb.connect(handler)

# Opens an external (parallel) process, executes the sequence, closes the process
def do_sequence(sequence):
    # Creates the external process
    sequence2do = multiprocessing.Process(target = farmbot_sequence, args = [sequence])
    
    # Starts the process
    sequence2do.start()

    # Ends the process
    last_log = get_lastlog()
    while last_log != 'Completed ' + sequence:
        if last_log == 'Completed ' + sequence:
            break
        last_log = get_lastlog()

    sequence2do.terminate()

# Get all sequences ID
sequences = get_sequencesID()

# Send initialization log
send_firstlog()

# Do sequence
for name in sequnece_names:
    do_sequence(name)

# Successfully completed
print('\n')
print('Farmbot_multiple_sequence_TEST - Successfully completed.\n\n')