import codecs
import csv
import os
from optparse import OptionParser

LOW_MAX_VALUE = 3
HIGH_MIN_VALUE = 4


class Stimuli(object):
    def __init__(self, start_onset_time, photo_onset_time, response):
        self.start_onset_time = start_onset_time
        self.photo_onset_time = photo_onset_time
        self.response = response


class Subject(object):
    def __init__(self, sub_id):
        self.id = sub_id
        self.stimuli_list = []

    def append_stimuli(self, start, photo, response):
        if start and photo and response:
            self.stimuli_list.append(Stimuli(int(start), int(photo), int(response)))

    def calculate_offsets(self):
        result = {'low': [], 'high': []}
        for stimuli in self.stimuli_list:
            diff = (stimuli.photo_onset_time - stimuli.start_onset_time) / 1000
            if stimuli.response <= LOW_MAX_VALUE:
                result.get('low').append(diff)
            elif stimuli.response >= HIGH_MIN_VALUE:
                result.get('high').append(diff)
        return result


def read_csv(filename):
    with codecs.open(filename, 'rU', 'utf-16LE') as file:
        reader = csv.DictReader(file, delimiter='\t')
        result = []
        for rows in reader:
            result.append(rows)
    return result


def generate_subjects(data, session_number):
    subjects = {}
    for row in data:
        sub_id = int(row.get('Subject'))
        session = int(row.get('Session'))
        start = row.get('start.OnsetTime')
        photo = row.get('Photo.OnsetTime')
        resp = row.get('Question.RESP')
        if int(session) == session_number:
            subject = subjects.get(sub_id, Subject(sub_id))
            subject.append_stimuli(start, photo, resp)
            subjects[sub_id] = subject
    return subjects


parser = OptionParser()
parser.add_option("-d", "--data", dest="csv_file",
                  help="Csv file generated by e-prime")
parser.add_option("-o", "--out-dir", dest="out_directory", default="output",
                  help="output directory")
parser.add_option("-s", "--session", dest="session", help="session number")
parser.add_option("--name", dest="name", help="Test name (will be included in output filenames)")

(options, args) = parser.parse_args()

if not options.csv_file:
    parser.error('Data file not given')

if not options.session:
    parser.error('Session number not given')

if not options.name:
    parser.error('Test name not given')

session = int(options.session)

data = read_csv(options.csv_file)
subjects = generate_subjects(data, session)

outdir = options.out_directory

if not os.path.exists(outdir):
    os.makedirs(outdir)

sub: Subject
for sub in subjects.values():
    offsets = sub.calculate_offsets()
    for k, v in offsets.items():
        sub_with_leading_zero = "{:02d}".format(sub.id)
        filename = '%s/sb%s.s%s.%s.f_%s.1D' % (outdir, sub_with_leading_zero, session, options.name, k)
        print('Generating file: %s' % filename)
        file_content = '\t'.join(map(str, v))
        with open(filename, 'w') as outfile:
            outfile.write(file_content)
