#!/usr/bin/python3

import argparse
import datetime
import json
import os
import random
import subprocess as sub
import signal
import sys
import time

terminate_test = False
def handler(signum, frame):
    global terminate_test
    terminate_test = True
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('output_dir', metavar='output_dir', type=str,
                    help='path to directory where results should be stored')

args = parser.parse_args()

experiment_time = 30

settings = [ 
    { 
        'frame_rate' : 20,
        'quantizer' : 26,
        'delay' : 5
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 26,
        'delay' : 10
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 26,
        'delay' : 20
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 33,
        'delay' : 1
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 33,
        'delay' : 5
    },
    {   
        'frame_rate' : 20,
        'quantizer' : 33,
        'delay' : 10
    },
    {   
        'frame_rate' : 20,
        'quantizer' : 33,
        'delay' : 20
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 40,
        'delay' : 1
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 40,
        'delay' : 5
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 40,
        'delay' : 10
    },
    { 
        'frame_rate' : 20,
        'quantizer' : 40,
        'delay' : 20
    }
]

random.shuffle(settings)
settings = [{ 
    'frame_rate' : 20,
    'quantizer' : 26,
    'delay' : 1
}] + settings


# create the output dir for the results
if os.path.isdir(args.output_dir):
    print('{} already exists. '.format(args.output_dir) + \
    'Please remove it before running the experiment')
    sys.exit(0)

os.makedirs(args.output_dir)

# serialize all the settings for this experiment
with open(os.path.join(args.output_dir, 'settings.json'), 'w') as f:
    metadata = dict()
    metadata['datetime'] = str(datetime.datetime.now())
    metadata['experiment_time'] = experiment_time
    metadata['settings'] = settings
    f.write(json.dumps(metadata, indent=4, sort_keys=True))

first = True
for setting in settings:
    if terminate_test:
        break

    # wait for participant to be ready        
    print(setting)
    input('Press [ENTER] to continue')

    # open up dir for this particular set of params to put results in
    results_dirname = 'f'+str(setting['frame_rate']) + '-' + \
                      'q'+str(setting['quantizer']) + '-' + \
                      'd'+ str(setting['delay'])
    
    results_dir_path = os.path.join(args.output_dir, results_dirname)
    os.makedirs(results_dir_path)

    p = sub.Popen(['./ps4_degrader', 
                   '-d', '0', 
                   '-m', '14',
                   '-p', '3',
                   '-v', 'video.raw',
                   '-l', '/dev/null'
                   '-b', str(2**20),
                   '-f', str(60 / setting['frame_rate']),
                   '-q', str(setting['quantizer']),
                   '-D', str(setting['delay']),
                   '-B', os.path.join(results_dir_path, 'beforeFile.raw'),
                   '-A', os.path.join(results_dir_path, 'afterFile.raw')],
                   stderr=open(os.path.join(results_dir_path, 'cerr.log'), 'w'),
                   stdout=open(os.path.join(results_dir_path, 'cout.log'), 'w'))

    print('  running')
    for i in range(10*experiment_time):
        if terminate_test:
            break
        time.sleep(1/10)

    if first:
       print('setting first to False')
       time.sleep(30)
       first = False
    
    p.send_signal(signal.SIGINT)
    time.sleep(2)
    p.kill()
    print('  done!')
