import requests as req
from automata.Eva import Eva
import time

ultimaker_url = 'http://169.254.74.221/api/v1/'

def get_ultimaker_auth():
    payload = {'application': 'python', 'user': 'Edd'}
    r = req.post(ultimaker_url + 'auth/request', data=payload)

    auth = req.auth.HTTPDigestAuth(r.json()['id'], r.json()['key'])

    print('Go to the printer to authorize...')
    while req.get(ultimaker_url + 'auth/check/' + auth.username, auth=auth).json()['message'] != 'authorized':
        time.sleep(1)

    return auth


def start_print_job(auth):
    while req.get(ultimaker_url + 'printer/status').json() != 'idle':
        # wait until there is no print job
        print('Printer is not ready to print...')
        time.sleep(1)

    print_file = {'file': open('UM3_automata_die.gcode', 'rb')}
    req.post(ultimaker_url + 'print_job', files=print_file, auth=auth)

    print('Printing...')


def wait_for_print_to_finish():
    while req.get(ultimaker_url + 'print_job/state').json() != 'printing':
        # wait for printer to start printing
        time.sleep(5)

    # get print time and sleep to avoid constantly polling API
    r = req.get(ultimaker_url + 'print_job')
    sleep_time = int(r.json()['time_total']) - int(r.json()['time_elapsed']) - 2
    if sleep_time <= 0:
        sleep_time = 1
    time.sleep(sleep_time)
    
    while req.get(ultimaker_url + 'print_job/state').json() != 'wait_cleanup':
        # wait until there is no print job
        time.sleep(1)

    print('Printer cleanup required...')


def main():
    eva_api_key = input('Enter API key: ')
    print('Connecting to Eva...')
    eva = Eva('192.168.1.245', eva_api_key)
    
    print('Connecting to Ultimaker...')
    auth = get_ultimaker_auth()

    print('Starting Eva toolpath...')
    with eva.lock():
            #if eva.gpio_get('d0', 'output') is True:
            eva.gpio_set('d0', False)
            eva.control_wait_for_ready()
            eva.toolpaths_use_saved(30)
            eva.control_home()
            eva.control_wait_for_ready()
            eva.control_run(loop=0, wait_for_ready=False)

    print('Starting print cycle...')
    dice_printed = 0
    while True:
        start_print_job(auth)
        wait_for_print_to_finish()

        print('Triggering Eva cleanup...')
        with eva.lock():
            eva.gpio_set('d0', True)

        # wait for Eva to finish cleanup
        print('Waiting for Eva to cleanup...')
        while eva.gpio_get('d0', 'output') is True:
            time.sleep(1)
            
        print('Eva cleanup finished...')

        dice_printed += 1
        print('{0} dice in the box'.format(dice_printed))


if __name__ == "__main__":
    main()

