import subprocess as sp
import argparse, os
from time import tzset
from os.path import join, dirname


def git_checkout(paths, date):
    """check out the git modules located in paths one by one in a subprocess with a commmit before a certain date

    Keyword arguments:
    paths -- a list of absolute paths to the git repos
    date -- a date (%Y-%M-%D) of which the immediately prior commit will be checked out
    """
    tz_cmds = 'echo "America/New_York" > /etc/timezone && ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime && '
    checkout_cmds = []
    for p in paths:
        checkout_cmds.append(f'cd {p} && git checkout -f $(git rev-list -1 --before="{date}" HEAD)')

    if len(checkout_cmds) == 1:
        cmd = checkout_cmds[0]
    else:
        cmd = " && ".join(checkout_cmds)
    cmd = tz_cmds + cmd
    # git checkout all the modules in one process
    sp.run(cmd, shell=True, check=True)


def init_submodules(path):
    """initialize a repo's submodules recursively"""
    sp.run(f"cd {path} && git submodule update --init --recursive", shell=True, check=True)


def find_submodules(path):
    """explore and return a list of submodule paths from a certain git repo at `path`

    Keyword arguments:
    path -- the aboslute path of git repo used as a root of finding its submodules
    """
    res = sp.run(f"find {path} -name .gitmodules", shell=True, check=True, capture_output=True)
    if res.stdout == "":
        return False

    submodules = []
    module_files = res.stdout.decode("utf-8").split("\n")
    for m in module_files:
        if m:
            with open(m) as f:
                submodule_root = dirname(m)
                module_paths = f.read().split("path = ")[1:]
                for p in module_paths:
                    submodule_path = join(submodule_root, p.split("\n")[0])
                    submodules.append(submodule_path)
    return submodules


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--src", required=True)
    parser.add_argument(
        "--date", required=True, help="date string used to find the commit (format: YYYY-MM-DD)"
    )
    args = parser.parse_args()

    git_checkout([args.src], args.date)
    init_submodules(args.src)
    files = find_submodules(args.src)
    git_checkout(files, args.date)
