"""Entry point module: process-chunk

Implements the entry-point by using Python or any other languages.
"""

import os
import re
import json
import sys
import subprocess
from time import sleep


def entry_point(chunk_id, system_cache_dir):
    """Method to complete: you have to raise an exception if an error occured
    in the program.

    Process a chunk.

    Args:
        chunk_id (str): Chunk id
        system_cache_dir (str): Path to system cache directory

    """
    path = os.path.dirname(__file__)
    temp_file = os.path.join(system_cache_dir, '%s_temp.txt' % (chunk_id))
    f = open(temp_file, 'r')
    files = f.readlines()
    f.close()
    files = [f.strip() for f in files]

    commands = []
    for i in range(len(files)):
        commands.append('python3 %s %s %s' % (
            os.path.join(path, 'process_video3.py'),
            files[i], system_cache_dir))

    gpu_ids = [0, 1, 2, 3]
    perGPU = 3
    pids = []
    i = 0

    for j, gpu in enumerate(gpu_ids):
        pids.append([])
        if i < len(commands):
            for k in range(perGPU):
                command = "CUDA_VISIBLE_DEVICES=%d %s" % (gpu, commands[i])
                pids[j].append(subprocess.Popen(command, shell=True))
                i += 1
                if i == len(commands):
                    break

    while i < len(commands):
        sleep(2)
        for j, gpu in enumerate(gpu_ids):
            if i < len(commands):
                for k in range(perGPU):
                    if j < len(pids) and k < len(pids[j]) and \
                       pids[j][k].poll() is not None:
                        command = "CUDA_VISIBLE_DEVICES=%d %s" % (
                            gpu, commands[i])
                        pids[j][k] = subprocess.Popen(command, shell=True)
                        i += 1
                        if i == len(commands):
                            break
    all_finished = False
    while not all_finished:
        sleep(120)
        all_finished = True
        for j, gpu in enumerate(gpu_ids):
            for k in range(perGPU):
                if j < len(pids) and k < len(pids[j]) and \
                   pids[j][k].poll() is None:
                    all_finished = False
