#! /usr/bin/env python3
import os
import sys
import glob
from trafficintelligence import storage, moving
import subprocess
import numpy as np


def loadParametersStartProcess(filename):
    # load initial parameters from x.txt
    f = open(filename, 'r+')
    l = f.readline()
    x = [s for s in l.strip().split(" ")]
    f.close()
    
    # create para-value list
    para = paraValueList(x)
    
    # run process including trackingfeature, groupfeature, load groundtruth, compute mota
    print(process(para, intersections, optimizeGroupingOnly))

def paraValueList(x):
    #create para-value list
    #list of the 8 parameters and their values
    pn = 8
    p = pn*[None]
    p[0] = '--feature-quality'             #]0.-0.4]
    p[1] = '--min-feature-distanceklt'     #]0.-6]
    p[2] = '--window-size'                 #[1-10]integer
    p[3] = '--min-tracking-error'          #[0.01-0.3]
    p[4] = '--min-feature-time'            #[2-100]integer
    p[5] = '--mm-connection-distance'      #[0.5-100]
    p[6] = '--mm-segmentation-distance'    #[1-100] ~mm-connection-distance / 2.5
    p[7] = '--min-nfeatures-group'         #[2-4]
    
    para = []
    for n in range(pn):
        para = para + [p[n],x[n]]
    
    return para

def process(para, intersections, optimizeGroupingOnly):
    Mota = []
    gtDatabaseaAbsPaths = []
    configFileAbsPaths = []

    cwd = os.getcwd()
    # move to the location of the intersection
    for intersectionPath in intersections:
        intersectionAbsPath = os.path.abspath(intersectionPath)
        os.chdir(intersectionAbsPath)
        # iterate through all the subdirectories to find ground truth sqlite files
        gtDatabaseaAbsPaths.extend([os.path.abspath(intersectionAbsPath + '/' + file) for file in glob.glob('**/*_gt.sqlite', recursive=True)])
        configFileAbsPaths.append(os.path.abspath(intersectionAbsPath + '/' + glob.glob('*.cfg', recursive=True)[0]))
        os.chdir(cwd)
    for gtDatabaseAbsPath, configFileAbsPath in zip(gtDatabaseaAbsPaths, configFileAbsPaths):
        gtDatabaseBasename = gtDatabaseAbsPath[:-10]
        videoFilename = gtDatabaseBasename + ".MP4"
        databaseFilename = gtDatabaseBasename + ".sqlite"
        gtDatabaseDirname = os.path.dirname(gtDatabaseAbsPath)
        homographyFilename = gtDatabaseDirname + "/homography.txt"
        maskFilename = gtDatabaseDirname + "/mask.png"
        # Skip feature tracking if the user specified to optimize only grouping parameters
        if not optimizeGroupingOnly:
            # Track features
            trackingFeature(para, configFileAbsPath, videoFilename, databaseFilename, homographyFilename, maskFilename)
        # Group features
        groupFeature(para, configFileAbsPath, videoFilename, databaseFilename, homographyFilename, maskFilename)
        #load trajectory
        objects = storage.loadTrajectoriesFromSqlite(databaseFilename, 'object')
        #load ground truth
        annotations = storage.loadTrajectoriesFromSqlite(gtDatabaseAbsPath, 'object')
        # Appending negative mota because nomad minimizes the output
        Mota.append(-computeMota(annotations, objects, Mota))
    
    # Change to the previous directory
    os.chdir(cwd)

    return np.mean(Mota)

def trackingFeature(para, config, video, db, homo, mask):
    # remove previous tracking
    if os.path.exists(db):
        os.remove(db)
    # trackingfeature command parameters
    tf = ['feature-based-tracking', config, '--tf', '--video-filename', video, '--database-filename', db, '--homography-filename', homo, '--mask-filename', mask]
    # run in command line and print directly
    subprocess.check_output(tf + para[0:10])

def groupFeature(para, config, video, db, homo, mask):
    #remove previous grouping
    storage.deleteFromSqlite(db, 'object')
    #groupfeature command parameters
    gf = ['feature-based-tracking', config, '--gf', '--video-filename', video, '--database-filename', db, '--homography-filename', homo, '--mask-filename', mask]
    #run in command line and print directly
    subprocess.check_output(gf + para[8:16])  # ['--min-feature-time', 'x', '--mm-connection-distance', 'x', '--mm-segmentation-distance', 'x', '--min-nfeatures-group', 'x']

def computeMota(annotations, objects, Mota):
    matchingDistance = 500
    firstInstant = 0
    lastInstant = 50000
    return moving.computeClearMOT(annotations, objects, matchingDistance, firstInstant, lastInstant)[1]


if __name__ == "__main__":
    # Load args that were given with select-arguments.py
    with open('arguments.txt', 'r') as f:
        args = f.read().split('\n')
        intersections = args[0]
        optimizeGroupingOnly = args[1]
        # Convert string representation of list into list
        intersections = eval(intersections)

    loadParametersStartProcess(sys.argv[1])
    sys.exit(0)

